跳至内容
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对象的 value 必须与页面名称中使用的参数匹配

  • 如果页面名称为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

除了params对象之外,当配置 i18n时,还可以返回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 会在第一次请求此类路径时提供页面的 “回退” 版本。网络爬虫(例如 Google)不会收到回退版本,而是会按照 fallback: 'blocking' 中的方式处理该路径。
  • 当通过 next/linknext/router(客户端)导航到具有 fallback: true 的页面时,Next.js **不会**提供回退版本,而是会按照 fallback: 'blocking' 中的方式处理该页面。
  • 在后台,Next.js 将静态生成请求的路径的 HTMLJSON。这包括运行 getStaticProps
  • 完成后,浏览器会接收生成的路径的 JSON。这将用于自动使用所需的 props 渲染页面。从用户的角度来看,页面将从回退页面切换到完整页面。
  • 同时,Next.js 将此路径添加到预渲染页面的列表中。后续对同一路径的请求将提供生成的页面,就像构建时预渲染的其他页面一样。

注意:使用 output: 'export' 时,不支持 fallback: true

何时使用 fallback: true

如果您的应用程序具有大量依赖于数据的静态页面(例如非常大的电子商务网站),则 fallback: true 很有用。如果您想预渲染所有产品页面,则构建将花费很长时间。

相反,您可以静态生成一小部分页面,并对其余页面使用 fallback: true。当有人请求尚未生成的页面时,用户将看到带有加载指示器或骨架组件的页面。

不久之后,getStaticProps 完成,页面将使用请求的数据进行渲染。从现在开始,每个请求同一页面的人都会获得静态预渲染的页面。

这确保用户始终拥有快速的体验,同时保持快速的构建和静态生成的优势。

fallback: true 不会更新生成的页面,请参阅 增量静态再生 以了解如何更新。

fallback: 'blocking'

如果 fallback'blocking',则 getStaticPaths 未返回的新路径将等待 HTML 生成(因此称为阻塞),然后将其缓存以供将来请求,因此每个路径只发生一次。

getStaticProps 的行为如下

  • getStaticPaths返回的路径将在构建时由getStaticProps渲染为HTML

  • 在构建时未生成的路径**不会**导致 404 页面。相反,Next.js 会在第一次请求时进行 SSR 并返回生成的 HTML
  • 完成后,浏览器会接收生成的路径的 HTML。从用户的角度来看,它将从“浏览器正在请求页面”过渡到“完整页面已加载”。没有加载/回退状态的闪烁。
  • 同时,Next.js 将此路径添加到预渲染页面的列表中。后续对同一路径的请求将提供生成的页面,就像构建时预渲染的其他页面一样。

默认情况下,fallback: 'blocking' 不会更新生成的页面。要更新生成的页面,请结合使用 增量静态再生fallback: 'blocking'

注意:使用 output: 'export' 时,不支持 fallback: 'blocking'

回退页面

在页面的“回退”版本中

  • 页面的 props 将为空。
  • 使用 路由器,您可以检测是否正在渲染回退,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 现在稳定,并简化了数据获取,包括 generateStaticParams()
v12.2.0按需增量静态再生 稳定。
v12.1.0添加了 按需增量静态再生(测试版)。
v9.5.0稳定的 增量静态再生
v9.3.0引入了 getStaticPaths