跳到內容
API 參考功能getStaticPaths

getStaticPaths

當從使用動態路由的頁面匯出名為 getStaticPaths 的函式時,Next.js 將會靜態預先渲染 getStaticPaths 指定的所有路徑。

pages/repo/[name].tsx
import type {
  InferGetStaticPropsType,
  GetStaticProps,
  GetStaticPaths,
} from 'next'
 
type Repo = {
  name: string
  stargazers_count: number
}
 
export const getStaticPaths = (async () => {
  return {
    paths: [
      {
        params: {
          name: 'next.js',
        },
      }, // See the "paths" section below
    ],
    fallback: true, // false or "blocking"
  }
}) satisfies GetStaticPaths
 
export const getStaticProps = (async (context) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}) satisfies GetStaticProps<{
  repo: Repo
}>
 
export default function Page({
  repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
  return repo.stargazers_count
}

getStaticPaths 傳回值

getStaticPaths 函式應傳回具有以下必要屬性的物件

paths

paths 鍵決定哪些路徑將被預先渲染。例如,假設您有一個使用動態路由的頁面,名為 pages/posts/[id].js。如果您從此頁面匯出 getStaticPaths,並為 paths 傳回以下內容

return {
  paths: [
    { params: { id: '1' }},
    {
      params: { id: '2' },
      // with i18n configured the locale for the path can be returned as well
      locale: "en",
    },
  ],
  fallback: ...
}

那麼,Next.js 將在 next build 期間,使用 pages/posts/[id].js 中的頁面元件,靜態產生 /posts/1/posts/2

每個 params 物件的值都必須與頁面名稱中使用的參數相符

  • 如果頁面名稱為 pages/posts/[postId]/[commentId],則 params 應包含 postIdcommentId
  • 如果頁面名稱使用捕捉所有路由區段,例如 pages/[...slug],則 params 應包含 slug(這是一個陣列)。如果此陣列為 ['hello', 'world'],則 Next.js 將靜態產生位於 /hello/world 的頁面。
  • 如果頁面使用選用捕捉所有路由,請使用 null[]undefinedfalse 來渲染最根部的路由。例如,如果您為 pages/[[...slug]] 提供 slug: false,Next.js 將靜態產生 / 頁面。

params 字串是區分大小寫的,理想情況下應標準化,以確保路徑正確產生。例如,如果為參數傳回 WoRLD,則只有在訪問的實際路徑為 WoRLD 時才會匹配,而不是 worldWorld

i18n 已設定時,除了 params 物件之外,還可以傳回 locale 欄位,這會設定所產生路徑的語系。

fallback: false

如果 fallbackfalse,則任何未由 getStaticPaths 傳回的路徑都將導致 404 頁面

當執行 next build 時,Next.js 將檢查 getStaticPaths 是否傳回 fallback: false,然後它將建置 getStaticPaths 傳回的路徑。如果您要建立的路徑數量很少,或者不常新增新的頁面資料,則此選項很有用。如果您發現需要新增更多路徑,並且您有 fallback: false,則需要再次執行 next build,以便可以產生新的路徑。

以下範例預先渲染每個名為 pages/posts/[id].js 的部落格文章。部落格文章列表將從 CMS 擷取,並由 getStaticPaths 傳回。然後,對於每個頁面,它使用 getStaticProps 從 CMS 擷取文章資料。

pages/posts/[id].js
function Post({ post }) {
  // Render post...
}
 
// This function gets called at build time
export async function getStaticPaths() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
 
  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false }
}
 
// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()
 
  // Pass post data to the page via props
  return { props: { post } }
}
 
export default Post

fallback: true

範例

如果 fallbacktrue,則 getStaticProps 的行為會以以下方式變更

  • getStaticPaths 傳回的路徑將在建置時由 getStaticProps 渲染為 HTML
  • 在建置時尚未產生的路徑不會導致 404 頁面。相反地,Next.js 將在第一次請求此類路徑時,提供頁面的「fallback」版本。網頁爬蟲程式(例如 Google)將不會收到 fallback,而是路徑的行為將如同 fallback: 'blocking'
  • 當透過 next/linknext/router(用戶端)導航到具有 fallback: true 的頁面時,Next.js 將不會提供 fallback,而是頁面的行為將如同 fallback: 'blocking'
  • 在背景中,Next.js 將靜態產生請求的路徑 HTMLJSON。這包括執行 getStaticProps
  • 完成後,瀏覽器會收到產生路徑的 JSON。這將用於自動渲染具有所需 props 的頁面。從使用者的角度來看,頁面將從 fallback 頁面切換到完整頁面。
  • 同時,Next.js 將此路徑新增至預先渲染頁面的清單中。後續對相同路徑的請求將提供產生的頁面,就像在建置時預先渲染的其他頁面一樣。

需知:當使用 output: 'export' 時,不支援 fallback: true

何時 fallback: true 有用?

如果您的應用程式有非常大量的靜態頁面(例如非常大型的電子商務網站),且這些頁面依賴資料,則 fallback: true 非常有用。如果您想要預先渲染所有產品頁面,則建置將需要很長時間。

相反地,您可以靜態產生一小部分的頁面,並將 fallback: true 用於其餘頁面。當有人請求尚未產生的頁面時,使用者將看到帶有載入指示器或骨架元件的頁面。

不久之後,getStaticProps 完成,頁面將使用請求的資料進行渲染。從現在開始,每個請求相同頁面的人都將獲得靜態預先渲染的頁面。

這確保使用者始終擁有快速的體驗,同時保留快速建置和靜態產生的優勢。

fallback: true 不會更新產生的頁面,若要更新產生的頁面,請查看漸進式靜態重新產生

fallback: 'blocking'

如果 fallback'blocking',則未由 getStaticPaths 傳回的新路徑將等待 HTML 產生,與 SSR 相同(因此稱為blocking),然後快取以供未來請求使用,因此每個路徑只會發生一次。

getStaticProps 的行為如下

  • getStaticPaths 傳回的路徑將在建置時由 getStaticProps 渲染為 HTML
  • 在建置時尚未產生的路徑不會導致 404 頁面。相反地,Next.js 將在第一次請求時執行 SSR 並傳回產生的 HTML
  • 完成後,瀏覽器會收到產生路徑的 HTML。從使用者的角度來看,它將從「瀏覽器正在請求頁面」轉換為「完整頁面已載入」。不會出現載入/fallback 狀態的閃爍。
  • 同時,Next.js 將此路徑新增至預先渲染頁面的清單中。後續對相同路徑的請求將提供產生的頁面,就像在建置時預先渲染的其他頁面一樣。

預設情況下,fallback: 'blocking' 不會更新產生的頁面。若要更新產生的頁面,請將漸進式靜態重新產生fallback: 'blocking' 結合使用。

需知:當使用 output: 'export' 時,不支援 fallback: 'blocking'

Fallback 頁面

在頁面的「fallback」版本中

  • 頁面的 props 將為空。
  • 使用 router,您可以偵測是否正在渲染 fallback,router.isFallback 將為 true

以下範例展示如何使用 isFallback

pages/posts/[id].js
import { useRouter } from 'next/router'
 
function Post({ post }) {
  const router = useRouter()
 
  // If the page is not yet generated, this will be displayed
  // initially until getStaticProps() finishes running
  if (router.isFallback) {
    return <div>Loading...</div>
  }
 
  // Render post...
}
 
// This function gets called at build time
export async function getStaticPaths() {
  return {
    // Only `/posts/1` and `/posts/2` are generated at build time
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    // Enable statically generating additional pages
    // For example: `/posts/3`
    fallback: true,
  }
}
 
// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()
 
  // Pass post data to the page via props
  return {
    props: { post },
    // Re-generate the post at most once per second
    // if a request comes in
    revalidate: 1,
  }
}
 
export default Post

版本歷史

版本變更
v13.4.0App Router 現在已穩定,具有簡化的資料fetch,包括 generateStaticParams()
v12.2.0隨需漸進式靜態重新產生已穩定。
v12.1.0新增隨需漸進式靜態重新產生(beta 版)。
v9.5.0穩定的漸進式靜態重新產生
v9.3.0引入 getStaticPaths