---
title: "预渲染"
description: "Nuxt 允许在构建时将页面静态渲染，以提升某些性能或 SEO 指标"
canonical_url: "https://nuxt.zhcndoc.com/docs/3.x/getting-started/prerendering"
---
# 预渲染

> Nuxt 允许在构建时将页面静态渲染，以提升某些性能或 SEO 指标

Nuxt 允许从你的应用中选择特定页面在构建时渲染。Nuxt 会在请求时直接提供预构建的页面，而不是实时生成它们。

::read-more{title="Nuxt rendering modes" to="https://nuxt.zhcndoc.com/docs/3.x/guide/concepts/rendering"}
::

## 基于爬虫的预渲染

使用 [`nuxt generate` 命令](https://nuxt.zhcndoc.com/docs/3.x/api/commands/generate)，通过 [Nitro](https://nuxt.zhcndoc.com/docs/3.x/guide/concepts/server-engine) 爬虫构建并预渲染你的应用。此命令类似于将 `nitro.static` 选项设为 `true` 的 `nuxt build`，或运行 `nuxt build --prerender`。

这将构建你的网站，启动一个 Nuxt 实例，并默认预渲染根页面`/`，以及该页面链接到的站点页面，接着这些页面又链接到的页面，如此类推。

::code-group{sync="pm"}
```bash [npm]
npx nuxt generate
```

```bash [yarn]
yarn nuxt generate
```

```bash [pnpm]
pnpm nuxt generate
```

```bash [bun]
bun x nuxt generate
```

```bash [deno]
deno x nuxt generate
```
::

你现在可以将`.output/public`目录部署到任何静态托管服务，或通过`npx serve .output/public`在本地预览它。

Nitro 爬虫的工作流程：

1. 加载应用根路由(`/`)的 HTML，你的`~/pages`目录中所有非动态页面的 HTML，以及`nitro.prerender.routes`数组中的任何其他路由。
2. 将 HTML 和`payload.json`保存到`~/.output/public/`目录，以便静态提供。
3. 在 HTML 中查找所有锚点标签（`<a href="...">`）以导航到其他路由。
4. 对找到的每个锚点重复步骤 1-3，直到没有更多锚点可供爬取。

理解这一点非常重要，因为未被任何可发现页面链接的页面无法自动预渲染。

### Payload 提取

Nuxt 会在 HTML 旁边生成 `_payload.json`，用于：

- 预渲染路由（在构建时）
- ISR/SWR 路由（在首次请求时）

Payload 包含来自 `useAsyncData` 和 `useFetch` 的序列化数据。客户端导航会加载这些缓存的 payload，而不是重新获取数据。使用路由规则：为诸如 `pages/[...slug].vue` 这样的动态路由配置 `'/**': { isr: true }`。

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/commands/generate"}
深入了解 `nuxt generate` 命令。
::

### 选择性预渲染

你可以在 `nuxt.config` 文件中手动指定 [Nitro](https://nuxt.zhcndoc.com/docs/3.x/guide/concepts/server-engine) 在构建期间获取并预渲染的路由，或忽略你不希望预渲染的路由，例如 `/dynamic`：

```ts twoslash [nuxt.config.ts]
// @errors: 2353
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/user/1', '/user/2'],
      ignore: ['/dynamic'],
    },
  },
})
```

你可以将其与`crawlLinks`选项结合使用，预渲染爬虫无法发现的一组路由，如`/sitemap.xml`或`/robots.txt`：

```ts twoslash [nuxt.config.ts]
// @errors: 2353
export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ['/sitemap.xml', '/robots.txt'],
    },
  },
})
```

将`nitro.prerender`设置为`true`相当于将`nitro.prerender.crawlLinks`设置为`true`。

::read-more{to="https://nitro.zhcndoc.com/config#prerender"}
在 Nitro 文档中了解更多关于预渲染的内容。
::

最后，你也可以使用`routeRules`手动配置：

```ts twoslash [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    // 设置 prerender 为 true 以配置该路由被预渲染
    "/rss.xml": { prerender: true },
    // 设置为 false 以跳过该路由的预渲染
    "/this-DOES-NOT-get-prerendered": { prerender: false },
    // /blog 下的所有路由只要被其他页面链接都会被预渲染
    "/blog/**": { prerender: true },
  },
})
```

::read-more{to="https://nitro.zhcndoc.com/config/#routerules"}
深入了解 Nitro 的`routeRules`配置。
::

作为简写，你也可以使用 [`defineRouteRules`](https://nuxt.zhcndoc.com/docs/3.x/api/utils/define-route-rules) 在页面文件中进行配置。

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/guide/going-further/experimental-features#inlinerouterules" icon="i-lucide-star"}
此功能为实验性功能，要使用它，你必须在 `nuxt.config` 中启用 `experimental.inlineRouteRules` 选项。
::

```vue [pages/index.vue]
<script setup>
// 也可以在页面级别设置
defineRouteRules({
  prerender: true,
})
</script>

<template>
  <div>
    <h1>主页</h1>
    <p>构建时预渲染</p>
  </div>
</template>
```

这会被转换为：

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
  },
})
```

## 运行时预渲染配置

### `prerenderRoutes`

你可以在 [Nuxt 上下文](https://nuxt.zhcndoc.com/docs/3.x/guide/going-further/nuxt-app#the-nuxt-context)中于运行时使用此函数，向 Nitro 添加更多要预渲染的路由。

```vue [pages/index.vue]
<script setup>
prerenderRoutes(['/some/other/url'])
prerenderRoutes('/api/content/article/my-article')
</script>

<template>
  <div>
    <h1>这将在预渲染时注册其他路由</h1>
  </div>
</template>
```

::read-more{title="prerenderRoutes" to="https://nuxt.zhcndoc.com/docs/3.x/api/utils/prerender-routes"}
::

### `prerender:routes` Nuxt 钩子

此钩子在预渲染之前调用，用于注册更多路由。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    async 'prerender:routes' (ctx) {
      const { pages } = await fetch('https://api.some-cms.com/pages').then(
        res => res.json(),
      )
      for (const page of pages) {
        ctx.routes.add(`/${page.name}`)
      }
    },
  },
})
```

### `prerender:generate` Nitro 钩子

此钩子在预渲染过程中针对每个路由调用，可用于对每个被预渲染的路由做细粒度处理。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  nitro: {
    hooks: {
      'prerender:generate' (route) {
        if (route.route?.includes('private')) {
          route.skip = true
        }
      },
    },
  },
})
```


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
