预渲染

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

Nuxt 允许从你的应用中选择页面在构建时进行渲染。Nuxt 会在请求时提供预构建的页面,而不是动态生成。

基于爬虫的预渲染

使用 nuxi generate 命令 通过 Nitro 爬虫构建和预渲染你的应用。此命令类似于设置了 nitro.statictruenuxt build,或运行 nuxt build --prerender。这将构建你的站点,启动一个 Nuxt 实例,并默认预渲染根页面 / 以及它链接到的任何站点页面、这些页面链接到的页面,依此类推。
npx nuxi generate
现在,你可以将 .output/public 目录部署到任何静态托管服务,或使用 npx serve .output/public 在本地预览。Nitro 爬虫的工作原理:
  1. 加载应用的根路由 (/)、你的 ~/pages 目录中的任何非动态页面,以及 nitro.prerender.routes 数组中的其他路由的 HTML。
  2. 将 HTML 和 payload.json 保存到 ~/.output/public/ 目录,以静态提供。
  3. 在 HTML 中查找所有锚标签 (<a href="...">) 以导航到其他路由。
  4. 对找到的每个锚标签重复步骤 1-3,直到没有更多锚标签可爬取。
理解这一点很重要,因为未链接到可发现页面的页面无法自动预渲染。
了解更多关于 nuxi generate 命令的信息。

选择性预渲染

你可以在 nuxt.config 文件中手动指定 Nitro 将在构建期间获取和预渲染的路由,或者忽略你不想预渲染的路由,例如 /dynamic
nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ["/user/1", "/user/2"],
      ignore: ["/dynamic"],
    },
  },
});
你可以结合 crawlLinks 选项预渲染爬虫无法发现的路由集,例如你的 /sitemap.xml/robots.txt
nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ["/sitemap.xml", "/robots.txt"],
    },
  },
});
nitro.prerender 设置为 true 等同于将 nitro.prerender.crawlLinks 设置为 true
在 Nitro 文档中了解更多关于预渲染的信息。
最后,你可以使用路由规则手动配置:
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 },
  },
});
了解更多关于 Nitro 的 routeRules 配置。
作为简写,你还可以在页面文件中使用 defineRouteRules 配置。
此功能为实验性功能,要使用它,你必须在 nuxt.config 中启用 experimental.inlineRouteRules 选项。
pages/index.vue
<script setup>
// 或在页面级别设置
defineRouteRules({
  prerender: true,
});
</script>

<template>
  <div>
    <h1>首页</h1>
    <p>在构建时预渲染</p>
  </div>
</template>
这将被翻译为:
nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    "/": { prerender: true },
  },
});

运行时预渲染配置

prerenderRoutes

你可以在 Nuxt 上下文 中运行时使用此功能,为 Nitro 添加更多需要预渲染的路由。
pages/index.vue
<script setup>
prerenderRoutes(["/some/other/url"]);
prerenderRoutes("/api/content/article/my-article");
</script>

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

prerender:routes Nuxt 钩子

在预渲染之前调用此钩子以注册额外的路由。
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 钩子

在预渲染期间为每个路由调用此钩子。你可以使用它对每个预渲染的路由进行精细处理。
nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    hooks: {
      "prerender:generate"(route) {
        if (route.route?.includes("private")) {
          route.skip = true;
        }
      },
    },
  },
});