Static Site Generation (SSG)
示例
- Agility CMS 示例 (演示)
- Builder.io 示例 (演示)
- ButterCMS 示例 (演示)
- Contentful 示例 (演示)
- Cosmic 示例 (演示)
- DatoCMS 示例 (演示)
- DotCMS 示例 (演示)
- Drupal 示例 (演示)
- Enterspeed 示例 (演示)
- GraphCMS 示例 (演示)
- Keystone 示例 (演示)
- Kontent.ai 示例 (演示)
- Makeswift 示例 (演示)
- Plasmic 示例 (演示)
- Prepr 示例 (演示)
- Prismic 示例 (演示)
- Sanity 示例 (演示)
- Sitecore XM Cloud 示例 (演示)
- Storyblok 示例 (演示)
- Strapi 示例 (演示)
- TakeShape 示例 (演示)
- Tina 示例 (演示)
- Umbraco 示例 (演示)
- Umbraco Heartcore 示例 (演示)
- Webiny 示例 (演示)
- WordPress 示例 (演示)
- 博客启动器示例 (演示)
- 静态推文(演示)
如果页面使用静态生成,则页面 HTML 在构建时生成。这意味着在生产环境中,页面 HTML 在您运行 next build
时生成。然后,此 HTML 将在每次请求时重复使用。它可以被 CDN 缓存。
在 Next.js 中,您可以使用或不使用数据静态生成页面。让我们来看看每种情况。
不使用数据的静态生成
默认情况下,Next.js 使用静态生成预渲染页面,而无需获取数据。这是一个例子
function About() {
return <div>About</div>
}
export default About
请注意,此页面不需要获取任何外部数据即可进行预渲染。在这种情况下,Next.js 在构建时为每个页面生成一个 HTML 文件。
使用数据的静态生成
某些页面需要在预渲染之前获取外部数据。 有两种情况,可能适用其中一种或两种。 在每种情况下,您都可以使用 Next.js 提供的这些函数。
- 您的页面内容依赖于外部数据:使用
getStaticProps
。 - 您的页面路径依赖于外部数据:使用
getStaticPaths
(通常与getStaticProps
结合使用)。
场景 1:您的页面内容依赖于外部数据
示例:您的博客页面可能需要从 CMS(内容管理系统)获取博客文章列表。
// TODO: Need to fetch `posts` (by calling some API endpoint)
// before this page can be pre-rendered.
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
为了在预渲染时获取此数据,Next.js 允许您从同一文件中 export
一个名为 getStaticProps
的 async
函数。 此函数在构建时被调用,并允许您将获取的数据传递到页面预渲染时的 props
中。
export default function Blog({ posts }) {
// Render posts...
}
// This function gets called at build time
export async function getStaticProps() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
要了解更多关于 getStaticProps
如何工作的信息,请查看数据获取文档。
场景 2:您的页面路径依赖于外部数据
Next.js 允许您创建带有动态路由的页面。 例如,您可以创建一个名为 pages/posts/[id].js
的文件,以根据 id
显示单个博客文章。 这将允许您在访问 posts/1
时显示 id: 1
的博客文章。
要了解更多关于动态路由的信息,请查看动态路由文档。
然而,您想在构建时预渲染哪个 id
可能取决于外部数据。
示例:假设您只在数据库中添加了一篇博客文章(id: 1
)。 在这种情况下,您只想在构建时预渲染 posts/1
。
稍后,您可能会添加第二篇带有 id: 2
的文章。 那么您也想预渲染 posts/2
。
因此,您的预渲染的页面路径依赖于外部数据。 为了处理这个问题,Next.js 允许您从动态页面(在本例中为 pages/posts/[id].js
)中 export
一个名为 getStaticPaths
的 async
函数。 此函数在构建时被调用,并允许您指定要预渲染的路径。
// 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 }
}
同样在 pages/posts/[id].js
中,您需要 export getStaticProps
,以便您可以获取有关此 id
的文章数据,并使用它来预渲染页面。
export default function Post({ post }) {
// Render post...
}
export async function getStaticPaths() {
// ...
}
// 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 } }
}
要了解更多关于 getStaticPaths
如何工作的信息,请查看数据获取文档。
我应该何时使用静态生成?
我们建议尽可能使用静态生成(无论是否带数据),因为您的页面可以构建一次并由 CDN 提供服务,这比让服务器在每次请求时都渲染页面要快得多。
您可以将静态生成用于多种类型的页面,包括
- 营销页面
- 博客文章和作品集
- 电子商务产品列表
- 帮助和文档
您应该问自己:“我可以在用户请求之前预渲染此页面吗?” 如果答案是肯定的,那么您应该选择静态生成。
另一方面,如果您无法在用户请求之前预渲染页面,那么静态生成不是一个好主意。 也许您的页面显示频繁更新的数据,并且页面内容在每次请求时都会更改。
在这种情况下,您可以执行以下操作之一
- 使用静态生成和客户端数据获取:您可以跳过预渲染页面的某些部分,然后使用客户端 JavaScript 来填充它们。 要了解更多关于这种方法的信息,请查看数据获取文档。
- 使用服务器端渲染:Next.js 在每次请求时预渲染页面。 这会比较慢,因为页面无法被 CDN 缓存,但预渲染的页面将始终是最新的。 我们将在下面讨论这种方法。
这对您有帮助吗?