getStaticPaths
当从使用 动态路由 的页面导出名为 getStaticPaths
的函数时,Next.js 将静态预渲染 getStaticPaths
指定的所有路径。
¥When exporting a function called getStaticPaths
from a page that uses Dynamic Routes, Next.js will statically pre-render all the paths specified by 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',
},
}, // 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
}
export async function getStaticPaths() {
return {
paths: [
{
params: {
name: 'next.js',
},
}, // See the "paths" section below
],
fallback: true, // false or "blocking"
}
}
export async function getStaticProps() {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}
export default function Page({ repo }) {
return repo.stargazers_count
}
getStaticPaths 返回值
¥getStaticPaths return values
getStaticPaths
函数应返回具有以下必需属性的对象:
¥The getStaticPaths
function should return an object with the following required properties:
paths
paths
键确定将预渲染哪些路径。例如,假设你有一个使用 动态路由 且名为 pages/posts/[id].js
的页面。如果你从此页面导出 getStaticPaths
并为 paths
返回以下内容:
¥The paths
key determines which paths will be pre-rendered. For example, suppose that you have a page that uses Dynamic Routes named pages/posts/[id].js
. If you export getStaticPaths
from this page and return the following for 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
。
¥Then, Next.js will statically generate /posts/1
and /posts/2
during next build
using the page component in pages/posts/[id].js
.
每个 params
对象的值必须与页面名称中使用的参数匹配:
¥The value for each params
object must match the parameters used in the page name:
-
如果页面名称为
pages/posts/[postId]/[commentId]
,则params
应包含postId
和commentId
。¥If the page name is
pages/posts/[postId]/[commentId]
, thenparams
should containpostId
andcommentId
. -
如果页面名称像
pages/[...slug]
一样使用 包罗万象的路由,那么params
应该包含slug
(这是一个数组)。如果这个数组是['hello', 'world']
,那么 Next.js 将静态生成/hello/world
处的页面。¥If the page name uses catch-all routes like
pages/[...slug]
, thenparams
should containslug
(which is an array). If this array is['hello', 'world']
, then Next.js will statically generate the page at/hello/world
. -
如果页面使用 可选的包罗万象的路由,则使用
null
、[]
、undefined
或false
来渲染最根路由。例如,如果你为pages/[[...slug]]
提供slug: false
,Next.js 将静态生成页面/
。¥If the page uses an optional catch-all route, use
null
,[]
,undefined
orfalse
to render the root-most route. For example, if you supplyslug: false
forpages/[[...slug]]
, Next.js will statically generate the page/
.
params
字符串区分大小写,理想情况下应进行标准化以确保正确生成路径。例如,如果参数返回 WoRLD
,则仅当 WoRLD
是实际访问的路径时才匹配,而不是 world
或 World
。
¥The params
strings are case-sensitive and ideally should be normalized to ensure the paths are generated correctly. For example, if WoRLD
is returned for a param it will only match if WoRLD
is the actual path visited, not world
or World
.
与 params
对象分开,当 i18n 已配置 时可以返回 locale
字段,该字段配置正在生成的路径的区域设置。
¥Separate of the params
object a locale
field can be returned when i18n is configured, which configures the locale for the path being generated.
fallback: false
如果 fallback
是 false
,则 getStaticPaths
未返回的任何路径都将导致 404 页面。
¥If fallback
is false
, then any paths not returned by getStaticPaths
will result in a 404 page.
当 next build
运行时,Next.js 将检查 getStaticPaths
是否返回 fallback: false
,然后它将仅构建 getStaticPaths
返回的路径。如果要创建的路径数量较少,或者不经常添加新页面数据,则此选项非常有用。如果你发现需要添加更多路径,并且你有 fallback: false
,则需要再次运行 next build
,以便可以生成新路径。
¥When next build
is run, Next.js will check if getStaticPaths
returned fallback: false
, it will then build only the paths returned by getStaticPaths
. This option is useful if you have a small number of paths to create, or new page data is not added often. If you find that you need to add more paths, and you have fallback: false
, you will need to run next build
again so that the new paths can be generated.
以下示例为每页预渲染一篇名为 pages/posts/[id].js
的博客文章。博客文章列表将从 CMS 获取并由 getStaticPaths
返回。然后,对于每个页面,它使用 getStaticProps
从 CMS 获取发布数据。
¥The following example pre-renders one blog post per page called pages/posts/[id].js
. The list of blog posts will be fetched from a CMS and returned by getStaticPaths
. Then, for each page, it fetches the post data from a CMS using getStaticProps
.
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
如果 fallback
是 true
,则 getStaticProps
的行为将发生以下变化:
¥If fallback
is true
, then the behavior of getStaticProps
changes in the following ways:
-
从
getStaticPaths
返回的路径将在构建时由getStaticProps
渲染到HTML
。¥The paths returned from
getStaticPaths
will be rendered toHTML
at build time bygetStaticProps
. -
构建时未生成的路径不会导致 404 页面。相反,Next.js 将在第一次请求此类路径时提供 “倒退” 版本的页面。网络爬虫(例如 Google)不会提供后备服务,路径的行为将与
fallback: 'blocking'
中相同。¥The paths that have not been generated at build time will not result in a 404 page. Instead, Next.js will serve a “fallback” version of the page on the first request to such a path. Web crawlers, such as Google, won't be served a fallback and instead the path will behave as in
fallback: 'blocking'
. -
当通过
next/link
或next/router
(客户端)导航到fallback: true
的页面时,Next.js 将不会提供回退服务,而是该页面将表现为fallback: 'blocking'
。¥When a page with
fallback: true
is navigated to throughnext/link
ornext/router
(client-side) Next.js will not serve a fallback and instead the page will behave asfallback: 'blocking'
. -
在后台,Next.js 会静态生成请求的路径
HTML
和JSON
。这包括运行getStaticProps
。¥In the background, Next.js will statically generate the requested path
HTML
andJSON
. This includes runninggetStaticProps
. -
完成后,浏览器会收到生成路径的
JSON
。这将用于自动渲染具有所需属性的页面。从用户的角度来看,页面将从后备页面交换到完整页面。¥When complete, the browser receives the
JSON
for the generated path. This will be used to automatically render the page with the required props. From the user’s perspective, the page will be swapped from the fallback page to the full page. -
同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像构建时预渲染的其他页面一样。
¥At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time.
很高兴知道:使用
output: 'export'
时不支持fallback: true
。¥Good to know:
fallback: true
is not supported when usingoutput: 'export'
.
fallback: true
什么时候有用?
¥When is fallback: true
useful?
如果你的应用有大量依赖于数据的静态页面(例如非常大的电子商务网站),则 fallback: true
非常有用。如果你想预渲染所有产品页面,则构建将花费很长时间。
¥fallback: true
is useful if your app has a very large number of static pages that depend on data (such as a very large e-commerce site). If you want to pre-render all product pages, the builds would take a very long time.
相反,你可以静态生成一小部分页面,并使用 fallback: true
来处理其余部分。当有人请求尚未生成的页面时,用户将看到带有加载指示器或骨架组件的页面。
¥Instead, you may statically generate a small subset of pages and use fallback: true
for the rest. When someone requests a page that is not generated yet, the user will see the page with a loading indicator or skeleton component.
不久之后,getStaticProps
完成,页面将使用请求的数据渲染。从现在开始,每个请求同一页面的人都将获得静态预渲染的页面。
¥Shortly after, getStaticProps
finishes and the page will be rendered with the requested data. From now on, everyone who requests the same page will get the statically pre-rendered page.
这确保用户始终拥有快速的体验,同时保留快速构建和静态生成的优势。
¥This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation.
fallback: true
不会更新生成的页面,请查看 增量静态再生。
¥fallback: true
will not update generated pages, for that take a look at Incremental Static Regeneration.
fallback: 'blocking'
如果 fallback
是 'blocking'
,则 getStaticPaths
未返回的新路径将等待生成 HTML
,与 SSR 相同(因此会阻塞),然后缓存以供将来的请求使用,因此每个路径仅发生一次。
¥If fallback
is 'blocking'
, new paths not returned by getStaticPaths
will wait for the HTML
to be generated, identical to SSR (hence why blocking), and then be cached for future requests so it only happens once per path.
getStaticProps
将表现如下:
¥getStaticProps
will behave as follows:
-
从
getStaticPaths
返回的路径将在构建时由getStaticProps
渲染到HTML
。¥The paths returned from
getStaticPaths
will be rendered toHTML
at build time bygetStaticProps
. -
构建时未生成的路径不会导致 404 页面。相反,Next.js 将在第一个请求上进行 SSR 并返回生成的
HTML
。¥The paths that have not been generated at build time will not result in a 404 page. Instead, Next.js will SSR on the first request and return the generated
HTML
. -
完成后,浏览器会收到生成路径的
HTML
。从用户的角度来看,它会从 "浏览器正在请求该页面" 过渡到 "整个页面已加载"。没有加载/回退状态的闪烁。¥When complete, the browser receives the
HTML
for the generated path. From the user’s perspective, it will transition from "the browser is requesting the page" to "the full page is loaded". There is no flash of loading/fallback state. -
同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像构建时预渲染的其他页面一样。
¥At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time.
fallback: 'blocking'
默认不会更新生成的页面。要更新生成的页面,请将 增量静态再生 与 fallback: 'blocking'
结合使用。
¥fallback: 'blocking'
will not update generated pages by default. To update generated pages, use Incremental Static Regeneration in conjunction with fallback: 'blocking'
.
很高兴知道:使用
output: 'export'
时不支持fallback: 'blocking'
。¥Good to know:
fallback: 'blocking'
is not supported when usingoutput: 'export'
.
后备页面
¥Fallback pages
在页面的“后备”版本中:
¥In the “fallback” version of a page:
-
该页面的 props 将为空。
¥The page’s props will be empty.
-
使用 router,你可以检测回退是否正在渲染,
router.isFallback
将是true
。¥Using the router, you can detect if the fallback is being rendered,
router.isFallback
will betrue
.
以下示例展示了如何使用 isFallback
:
¥The following example showcases using isFallback
:
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
版本历史
¥Version History
版本 | 变化 |
---|---|
v13.4.0 | 应用路由 现已稳定,数据获取已简化,包括 generateStaticParams() |
v12.2.0 | 按需增量静态再生 稳定。 |
v12.1.0 | 添加了 按需增量静态再生(测试版)。 |
v9.5.0 | 稳定 增量静态再生 |
v9.3.0 | getStaticPaths 推出。 |