getStaticPaths

如果頁面具有動態路由 (Dynamic Routes) 並使用 getStaticProps,則需要定義要靜態生成的路徑列表。

當您從使用動態路由的頁面導出名為 getStaticPaths 的函數(靜態網站生成)時,Next.js 將靜態預渲染 getStaticPaths 指定的所有路徑。

import type {
  InferGetStaticPropsType,
  GetStaticProps,
  GetStaticPaths,
} from 'next'

type Repo = {
  name: string
  stargazers_count: number
}

export const getStaticPaths = (async () => {
  return {
    paths: [
      {
        params: {
          name: 'next.js',
        },
      }, // 請參閱下方的 "paths" 部分
    ],
    fallback: true, // false 或 "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 (headless CMS)
  • 資料來自資料庫
  • 資料來自檔案系統
  • 資料可以公開快取(非用戶特定)
  • 頁面必須預渲染(為了 SEO)且速度非常快 — getStaticProps 生成 HTMLJSON 文件,兩者都可以由 CDN 快取以提高性能

getStaticPaths 何時執行

getStaticPaths 僅在生產環境的建置期間執行,不會在運行時調用。您可以使用此工具驗證 getStaticPaths 內部的代碼已從客戶端套件中移除。

getStaticProps 如何與 getStaticPaths 一起運行

  • getStaticPropsnext build 期間為建置時返回的任何 paths 運行
  • 使用 fallback: true 時,getStaticProps 會在背景運行
  • 使用 fallback: blocking 時,getStaticProps 會在初始渲染前調用

可以在哪裡使用 getStaticPaths

  • getStaticPaths 必須getStaticProps 一起使用
  • 不能getStaticPathsgetServerSideProps 一起使用
  • 可以從同時使用 getStaticProps動態路由 (Dynamic Route) 導出 getStaticPaths
  • 不能從非頁面文件(例如 components 資料夾)導出 getStaticPaths
  • 必須將 getStaticPaths 作為獨立函數導出,而不是頁面組件的屬性

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

在開發環境 (next dev) 中,getStaticPaths 會在每次請求時調用。

按需生成路徑

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

您可以通過為 paths 返回空數組來延遲按需生成所有頁面。這在將 Next.js 應用程式部署到多個環境時特別有用。例如,您可以通過為預覽環境(而非生產建置)按需生成所有頁面來加快建置速度。這對於具有數百/數千個靜態頁面的網站非常有用。

pages/posts/[id].js
export async function getStaticPaths() {
  // 當此值為 true 時(在預覽環境中)
  // 不預渲染任何靜態頁面
  // (建置速度更快,但初始頁面加載速度較慢)
  if (process.env.SKIP_BUILD_STATIC_GENERATION) {
    return {
      paths: [],
      fallback: 'blocking',
    }
  }

  // 調用外部 API 端點獲取文章
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 根據文章獲取我們想要預渲染的路徑
  // 在生產環境中,預渲染所有頁面
  // (建置速度較慢,但初始頁面加載速度更快)
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // { fallback: false } 表示其他路由應返回 404
  return { paths, fallback: false }
}

On this page