跳至內容

getStaticPaths

如果一個頁面具有動態路由並使用 getStaticProps,則需要定義要靜態生成的路径列表。

當您從使用動態路由的頁面匯出名為 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 API 參考涵蓋了所有可與 getStaticPaths 一起使用的參數和屬性。

何時應該使用 getStaticPaths?

如果您正在靜態預渲染使用動態路由的頁面,並且符合以下情況,則應該使用 getStaticPaths

  • 資料來自無頭 CMS
  • 資料來自資料庫
  • 資料來自檔案系統
  • 資料可以公開快取(非使用者特定)
  • 頁面必須預先渲染(為了 SEO)並且速度非常快 — getStaticProps 會產生 HTMLJSON 檔案,這兩者都可以由 CDN 快取以提升效能

getStaticPaths 何時執行

getStaticPaths 只會在正式環境的建置期間執行,在執行期間不會被呼叫。您可以使用這個工具驗證寫在 getStaticPaths 裡的程式碼已從客戶端套件中移除。

getStaticProps 如何與 getStaticPaths 搭配執行

  • next build 期間,getStaticProps 會針對建置期間返回的任何 paths 執行
  • 當使用 fallback: true 時,getStaticProps 會在背景執行
  • 當使用 fallback: blocking 時,getStaticProps 會在初始渲染之前被呼叫

在哪裡可以使用 getStaticPaths

  • getStaticPaths 必須getStaticProps 一起使用
  • 不能getStaticPathsgetServerSideProps 一起使用
  • 您可以從也使用 getStaticProps動態路由匯出 getStaticPaths
  • 不能從非頁面檔案(例如您的 components 資料夾)匯出 getStaticPaths
  • 您必須將 getStaticPaths 作為獨立函式匯出,而不是頁面組件的屬性。

在開發環境中,每次請求都會執行

在開發環境 (next dev) 中,每次請求都會呼叫 getStaticPaths

依需求產生路徑

getStaticPaths 允許您控制在建置期間產生的頁面,而不是使用 fallback 依需求產生。在建置期間產生更多頁面會導致建置速度變慢。

您可以藉由傳回一個空的 paths 陣列來延遲依需求產生所有頁面。這在將 Next.js 應用程式部署到多個環境時特別有用。例如,您可以透過依需求產生預覽的所有頁面(而不是正式版建置)來加快建置速度。這對於具有數百/數千個靜態頁面的網站很有幫助。

pages/posts/[id].js
export async function getStaticPaths() {
  // When this is true (in preview environments) don't
  // prerender any static pages
  // (faster builds, but slower initial page load)
  if (process.env.SKIP_BUILD_STATIC_GENERATION) {
    return {
      paths: [],
      fallback: 'blocking',
    }
  }
 
  // 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 prerender based on posts
  // In production environments, prerender all pages
  // (slower builds, but faster initial page load)
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
 
  // { fallback: false } means other routes should 404
  return { paths, fallback: false }
}