Skip to main content

getStaticProps

如果你从页面导出名为 getStaticProps(静态站点生成)的函数,Next.js 将在构建时使用 getStaticProps 返回的 props 预渲染此页面。

¥If you export a function called getStaticProps (Static Site Generation) from a page, Next.js will pre-render this page at build time using the props returned by getStaticProps.

import type { InferGetStaticPropsType, GetStaticProps } from 'next'

type Repo = {
name: string
stargazers_count: number
}

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 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
}

请注意,无论渲染类型如何,任何 props 都将传递到页面组件,并且可以在客户端的初始 HTML 中查看。这是为了让页面正确为 hydrated。确保你没有传递任何不应在 props 中的客户端上可用的敏感信息。

¥Note that irrespective of rendering type, any props will be passed to the page component and can be viewed on the client-side in the initial HTML. This is to allow the page to be hydrated correctly. Make sure that you don't pass any sensitive information that shouldn't be available on the client in props.

getStaticProps API 参考 涵盖了可与 getStaticProps 一起使用的所有参数和属性。

¥The getStaticProps API reference covers all parameters and props that can be used with getStaticProps.

我什么时候应该使用 getStaticProps?

¥When should I use getStaticProps?

如果出现以下情况,你应该使用 getStaticProps

¥You should use getStaticProps if:

  • 渲染页面所需的数据可在用户请求之前的构建时提供

    ¥The data required to render the page is available at build time ahead of a user’s request

  • 数据来自无头 CMS

    ¥The data comes from a headless CMS

  • 页面必须预渲染(用于 SEO)并且速度非常快 — getStaticProps 生成 HTMLJSON 文件,这两个文件都可以由 CDN 缓存以提高性能

    ¥The page must be pre-rendered (for SEO) and be very fast — getStaticProps generates HTML and JSON files, both of which can be cached by a CDN for performance

  • 数据可以公开缓存(不是特定于用户的)。在某些特定情况下,可以通过使用中间件重写路径来绕过此条件。

    ¥The data can be publicly cached (not user-specific). This condition can be bypassed in certain specific situation by using a Middleware to rewrite the path.

getStaticProps 何时运行

¥When does getStaticProps run

getStaticProps 始终在服务器上运行,从不在客户端上运行。你可以验证 getStaticProps 内编写的代码是否已从客户端打包包 用这个工具 中删除。

¥getStaticProps always runs on the server and never on the client. You can validate code written inside getStaticProps is removed from the client-side bundle with this tool.

  • getStaticProps 始终在 next build 期间运行

    ¥getStaticProps always runs during next build

  • 使用 fallback: truegetStaticProps 在后台运行

    ¥getStaticProps runs in the background when using fallback: true

  • 使用 fallback: blocking 时,在初始渲染之前调用 getStaticProps

    ¥getStaticProps is called before initial render when using fallback: blocking

  • 使用 revalidategetStaticProps 在后台运行

    ¥getStaticProps runs in the background when using revalidate

  • 使用 revalidate() 时,getStaticProps 在后台按需运行

    ¥getStaticProps runs on-demand in the background when using revalidate()

当与 增量静态再生 结合使用时,getStaticProps 将在后台运行,同时重新验证过时页面,并将新页面提供给浏览器。

¥When combined with Incremental Static Regeneration, getStaticProps will run in the background while the stale page is being revalidated, and the fresh page served to the browser.

getStaticProps 无权访问传入请求(例如查询参数或 HTTP 标头),因为它生成静态 HTML。如果你需要访问你页面的请求,除了 getStaticProps 之外,还可以考虑使用 中间件

¥getStaticProps does not have access to the incoming request (such as query parameters or HTTP headers) as it generates static HTML. If you need access to the request for your page, consider using Middleware in addition to getStaticProps.

使用 getStaticProps 从 CMS 获取数据

¥Using getStaticProps to fetch data from a CMS

以下示例展示了如何从 CMS 获取博客文章列表。

¥The following example shows how you can fetch a list of blog posts from a CMS.

// posts will be populated at build time by getStaticProps()
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
// Call an external API endpoint to get posts.
// You can use any data fetching library
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,
},
}
}
// posts will be populated at build time by getStaticProps()
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
// Call an external API endpoint to get posts.
// You can use any data fetching library
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 API 参考 涵盖了可与 getStaticProps 一起使用的所有参数和属性。

¥The getStaticProps API reference covers all parameters and props that can be used with getStaticProps.

直接编写服务器端代码

¥Write server-side code directly

由于 getStaticProps 仅在服务器端运行,因此它永远不会在客户端运行。它甚至不会包含在浏览器的 JS 包中,因此你可以编写直接的数据库查询,而无需将它们发送到浏览器。

¥As getStaticProps runs only on the server-side, it will never run on the client-side. It won’t even be included in the JS bundle for the browser, so you can write direct database queries without them being sent to browsers.

这意味着你可以直接在 getStaticProps 中编写服务器端代码,而不是从 getStaticProps 获取 API 路由(本身从外部源获取数据)。

¥This means that instead of fetching an API route from getStaticProps (that itself fetches data from an external source), you can write the server-side code directly in getStaticProps.

以下面的例子为例。API 路由用于从 CMS 获取一些数据。然后直接从 getStaticProps 调用该 API 路由。这会产生额外的调用,从而降低性能。相反,可以使用 lib/ 目录共享从 CMS 获取数据的逻辑。然后就可以和 getStaticProps 共享了。

¥Take the following example. An API route is used to fetch some data from a CMS. That API route is then called directly from getStaticProps. This produces an additional call, reducing performance. Instead, the logic for fetching the data from the CMS can be shared by using a lib/ directory. Then it can be shared with getStaticProps.

// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts/')
const data = await res.json()

return data
}
// pages/blog.js
import { loadPosts } from '../lib/load-posts'

// This function runs only on the server side
export async function getStaticProps() {
// Instead of fetching your `/api` route you can call the same
// function directly in `getStaticProps`
const posts = await loadPosts()

// Props returned will be passed to the page component
return { props: { posts } }
}

或者,如果你不使用 API 路由来获取数据,则可以在 getStaticProps 中直接使用 fetch() API 来获取数据。

¥Alternatively, if you are not using API routes to fetch data, then the fetch() API can be used directly in getStaticProps to fetch data.

要验证 Next.js 从客户端包中删除了哪些内容,你可以使用 下一个代码消除工具.js 文件。

¥To verify what Next.js eliminates from the client-side bundle, you can use the next-code-elimination tool.

静态生成 HTML 和 JSON

¥Statically generates both HTML and JSON

当在构建时预渲染带有 getStaticProps 的页面时,除了页面 HTML 文件之外,Next.js 还会生成一个 JSON 文件,其中保存运行 getStaticProps 的结果。

¥When a page with getStaticProps is pre-rendered at build time, in addition to the page HTML file, Next.js generates a JSON file holding the result of running getStaticProps.

该 JSON 文件将用于通过 next/linknext/router 的客户端路由。当你导航到使用 getStaticProps 预渲染的页面时,Next.js 会获取此 JSON 文件(在构建时预先计算)并将其用作页面组件的 props。这意味着客户端页面转换不会调用 getStaticProps,因为仅使用导出的 JSON。

¥This JSON file will be used in client-side routing through next/link or next/router. When you navigate to a page that’s pre-rendered using getStaticProps, Next.js fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will not call getStaticProps as only the exported JSON is used.

当使用增量静态生成时,getStaticProps 将在后台执行以生成客户端导航所需的 JSON。你可能会以对同一页面发出多个请求的形式看到这种情况,但是,这是有意的,对终端用户的性能没有影响。

¥When using Incremental Static Generation, getStaticProps will be executed in the background to generate the JSON needed for client-side navigation. You may see this in the form of multiple requests being made for the same page, however, this is intended and has no impact on end-user performance.

在哪里可以使用 getStaticProps

¥Where can I use getStaticProps

getStaticProps 只能从页面导出。你无法从非页面文件、_app_document_error 导出它。

¥getStaticProps can only be exported from a page. You cannot export it from non-page files, _app, _document, or _error.

造成此限制的原因之一是 React 在渲染页面之前需要拥有所有必需的数据。

¥One of the reasons for this restriction is that React needs to have all the required data before the page is rendered.

另外,你必须将导出 getStaticProps 作为独立函数使用 - 如果你将 getStaticProps 添加为页面组件的属性,则它将不起作用。

¥Also, you must use export getStaticProps as a standalone function — it will not work if you add getStaticProps as a property of the page component.

很高兴知道:如果你创建了 定制应用,请确保将 pageProps 传递到页面组件,如链接文档中所示,否则属性将为空。

¥Good to know: if you have created a custom app, ensure you are passing the pageProps to the page component as shown in the linked document, otherwise the props will be empty.

根据开发中的每个请求运行

¥Runs on every request in development

在开发中 (next dev),每个请求都会调用 getStaticProps

¥In development (next dev), getStaticProps will be called on every request.

预览模式

¥Preview Mode

你可以暂时绕过静态生成并在请求时而不是使用 预览模式 构建时渲染页面。例如,你可能正在使用无头 CMS,并希望在发布草稿之前对其进行预览。

¥You can temporarily bypass static generation and render the page at request time instead of build time using Preview Mode. For example, you might be using a headless CMS and want to preview drafts before they're published.