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

  • 資料來自無頭內容管理系統 (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