如果一个页面有动态路由(文档)并且使用
getStaticProps
,则需要定义在构建过程中必须渲染为 HTML 的路径列表。
如果你从使用动态路由的页面中导出一个称为 getStaticProps
的 async
函数
,Blitz 将静态地预渲染 getStaticPaths
指定的所有路径。
export async function getStaticPaths() {
return {
paths: [
{ params: { ... } } // 查阅下方 "paths" 章节
],
fallback: true or false // 查阅下方 "fallback" 章节
};
}
paths
键(必须)paths
键确定了哪些路径将被预渲染。例如,假设你有一个页面使用动态路由的名
为 app/posts/pages/posts/[id].js
的文件。如果你从这个页面导出
getStaticPaths
并为 path
返回以下内容:
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } }
],
fallback: ...
}
那么 Blitz 将会在 app/posts/pages/posts/[id].js
页面组件的构建过程中静态
生成 posts/1
和 posts/2
。
请注意,每个 params
的值必须与页面名称中使用的参数匹配:
app/posts/pages/posts/[postId]/[commentId]
,那么
params
应该包括 postId
和 commentId
。pages/[...slug]
,那么
params
应该包含值为数组的 slug
。例如,如果这个数组是
['foo', 'bar']
,那么 Blitz 会为 /foo/bar
静态生成页面。null
、[]
、undefined
或 faluse
来渲染最根目录的路由。例如,如果你
为 pages/[[...slug]]
提供 slug: false
,Blitz 会静态生成页面 /
。fallback
键(必须)getStaticPaths
返回的对象必须包含一个布尔值的 fallback
键。
fallback: false
如果 fallback
是 false
,那么没有被 getStaticPaths
返回的任何路径将会
导致一个 404 页面。当你有一个数量少的路径来渲染的时候可以这么做——因此
这些是在构建过程中静态生成的。当新的页面不常被更新的时候也会很有用。如果你
要为数据源新增很多元素并且需要渲染新的页面,你最好再次执行构建。
这是一个 app/posts/pages/posts/[id].js
示例,其中每页渲染一个博客文章。
博客文章的类别将从你的数据库或 CMS 获取,并由 getStaticPaths
返回。接着
,针对每个页面,使用 getStaticPaths
获取单个文章的数据。
// app/posts/pages/posts/[id].js
function Post({post}) {
// 渲染文章...
}
// 该函数在预渲染时被调用
export async function getStaticPaths() {
// 1. 使用 blitz query 来获取所有文章
// 2. 或调用外部 API 端口来获取文章
const posts = /* ... */
// 基于 posts 获取我们想要预渲染的路径
const paths = posts.map((post) => ({
params: {id: post.id},
}))
// 我们将只在构建过程中预渲染这些路径
// { fallback: false } 意味着其它路由将会 404。
return {paths, fallback: false}
}
// 这个也在构建过程中被调用
export async function getStaticProps({params}) {
// params 包含文章 `id`。
// 如果路由像 /posts/1 这样,那么 params.id 就是 1
const post = /* get one post */
// 通过 props 来传递文章数据到页面中
return {props: {post}}
}
export default Post
fallback: true
如果 fallback
是 true
,那么 getStatickProps
改变时的行为是:
getStaticPaths
返回的路径将会在构建过程中被渲染为 HTML。getStaticProps
。在页面的 “fallback” 版本中:
router.isFallback
将会为 true
。这是一个使用 isFallback
的示例:
// app/posts/pages/posts/[id].js
import {useRouter} from "blitz"
function Post({post}) {
const router = useRouter()
// 如果当前页面还没被生成,则将最初显示如下加载动画,直到 `getStaticProps` 运行完成为止。
if (router.isFallback) {
return <div>Loading...</div>
}
// 渲染文章...
}
// 该函数在构建过程中被调用
export async function getStaticPaths() {
return {
// 仅仅 `/posts/1` 和 /posts/2/ 在构建过程中被生成。
paths: [{params: {id: "1"}}, {params: {id: "2"}}],
// 启用静态生成额外页面:
// 例如:`/posts/3`
fallback: true,
}
}
// 这也在构建过程中被调用
export async function getStaticProps({params}) {
// 参数包含文章 `id`。
// 如果路由像 /posts/1,那么 params.id 是 1
const post = /* ... */
// 通过 props 来传递文章数据到页面中
return {props: {post}}
}
export default Post
fallback: true
什么时候有用?如果你的应用具有大量依赖于数据的静态页面(请想象:一个很大的电商网站)时
,fallback: true
将会很有用。你想要预渲染所有产品页面的话,你的构建过程
将会非常之久。
相反,你可以静态生成页面的一小部分,其余部分使用 fallback: true
。当有人
请求尚未生成的页面时,用户将看到带有加载动画的页面。此后不久
,getStaticProps
完成,此页面将使用刚请求的数据渲染。从现在开始,请求同
一个页面的每个人都将获得静态预渲染的页面。
这可以确保用户在保持快速构建的同时始终能获得快速的体验,并获得“静态生成”的 好处。
fallback: true
将不会 更新 生成的页面,相关请查
阅增量静态再生。
fallback: 'blocking'
如果 fallback
被 'blocking'
,新的没有被 getStaticPaths
返回的路径将
生成 HTML,该 HTML 与 SSR 相同(因此为何 blocking),然后被缓存以用于将
来的请求,因此每个路径仅产生一次。
getStaticProps
的表现形式如下:
getStaticPath
返回的路径将被 getStaticProps
在构建过程渲染为 HTML。fallback: 'blocking'
将默认不会更新已生成的页面。要更新已生成的页面
,请结合使
用增量静态再生
和 fallback: 'blocking'
。
getStaticPaths
?如果你要静态预渲染使用动态路由的页面,则应使用 getStaticPaths
。
GetStaticPaths
对于 TypeScript,你可以使用 blitz
中的 GetStaticPaths
类型:
import { GetStaticPaths } from "blitz"
export const getStaticPaths: GetStaticPaths = async () => {
// ...
}
getStaticProps
搭配使用当你在有动态路由参数的页面中使用 getStaticProps
时,你必须使用
getStaticPaths
。
你无法和 getServerSideProps
一起使用 getStaticPaths
。
getStaticPaths
仅在服务端构建过程中执行。
getStaticPaths
仅能从一个页面中导出。你无法从一个非页面文件中导出。
同时,你必须使用 export async function getStaticPaths() {}
——如果你将
getStaticPaths
作为一个页面组件的属性,它将不能运行。
在开发环境中(blitz dev
),getStaticPaths
将会在每一次请求中被调用。