预渲染

在构建时渲染路由,并将其作为静态资源提供

启用预渲染后,Nitro 会在构建期间获取指定路由,并将响应写入 .output/public 目录。预渲染的路由随后会作为静态文件提供。请求时不会进行服务器渲染,因此这些路由速度快、可缓存,并且可以部署到任意静态托管服务或 CDN。

预渲染适用于内容不会随请求变化的路由:落地页、文档、博客文章,或输出内容固定的 JSON 端点。动态路由仍然可以继续由服务器提供,并且你可以在同一个应用中自由混合预渲染路由和服务器渲染路由。

#预渲染路由

#prerender.routes 配置

使用 prerender.routes 选项列出要预渲染的路由:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  prerender: {
    routes: ["/", "/about", "/api/content.json"],
  },
});

HTML 响应会作为 index.html 文件写入子文件夹中(/about 会生成 about/index.html),而其他响应会保留其路径(/api/content.json 会生成 api/content.json)。请参阅 autoSubfolderIndex 以更改此行为。

#prerender 路由规则

或者,使用 prerender 路由规则将路由标记为预渲染:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  routeRules: {
    "/about": { prerender: true },
  },
});

Warning

路由规则只会将完全匹配的路径添加到预渲染列表中。像 "/blog/**": { prerender: true } 这样的通配符模式不会自动展开,因为 Nitro 无法知道哪些路由与该模式匹配。要预渲染一组动态路由,请使用链接爬取prerender:routes hook

#爬取链接

除了(或作为补充)列出每个路由之外,还可以启用 crawlLinks,让 Nitro 通过跟随预渲染 HTML 页面中的链接来发现路由:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  prerender: {
    crawlLinks: true,
    routes: ["/"],
  },
});

爬虫会从每个预渲染 HTML 页面中提取 href 属性,并将发现的路由加入预渲染队列。外部链接、哈希链接,以及指向带扩展名文件的链接(.json 除外)都会被跳过。相对链接会根据其所在页面进行解析。

如果启用了 crawlLinks 且未指定路由,爬取会从 / 开始。

Tip

处理程序可以通过将 x-nitro-prerender 响应标头设置为以逗号分隔的路径列表,来为预渲染添加其他路由。即使禁用了 crawlLinks,此功能仍然有效。

#忽略路由

使用 prerender.ignore 跳过路由。每个条目可以是字符串前缀、正则表达式,或接收路径的函数:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  prerender: {
    crawlLinks: true,
    ignore: [
      "/admin",                        // Ignore routes starting with /admin
      /\/preview$/,                     // Ignore routes ending with /preview
      (path) => path.includes("draft"), // Ignore routes containing "draft"
    ],
  },
});

你也可以使用 prerender: false 路由规则排除路由。与启用预渲染不同,通配符模式可以用于排除,因为它们会针对每个候选路由进行匹配:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  routeRules: {
    "/dynamic/**": { prerender: false },
  },
});

#公共资源

由带有基础 URL 前缀的公共资源提供的路由始终会被跳过。此外,你可以设置 prerender.ignoreUnprefixedPublicAssets: true,跳过已经由不带前缀的公共资源提供的路由,从而避免输出中出现重复文件:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  prerender: {
    crawlLinks: true,
    ignoreUnprefixedPublicAssets: true,
  },
});

#选项

选项默认值描述
failOnErrorfalse当路由无法预渲染时使构建失败。适用于 CI。
retry3失败路由的重试次数。传入 Infinity 可无限重试。
retryDelay500每次重试之间的延迟时间,单位为毫秒。
concurrency1并行预渲染的最大路由数。
interval0预渲染请求之间的延迟时间,单位为毫秒。
autoSubfolderIndextrue将 HTML 路由写入子文件夹索引文件。

Note

retryretryDelay 选项可以在配置中接受,但当前的 v3 预渲染器尚未应用它们。

concurrencyinterval 选项控制预渲染速度。提高 concurrency 可以加快大型网站的速度,或者添加 interval,以避免路由调用外部 API 时触发速率限制。

autoSubfolderIndex 控制 HTML 文件写入 .output/public 的方式:

# autoSubfolderIndex: true (default)
/about -> .output/public/about/index.html
# autoSubfolderIndex: false
/about -> .output/public/about.html

当你的托管服务提供商不允许配置尾部斜杠行为时,将其设置为 false

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  prerender: {
    crawlLinks: true,
    failOnError: true,
    concurrency: 8,
    autoSubfolderIndex: false,
  },
});

#Hooks

对于高级用例,你可以在构建时接入预渲染生命周期。这些 hooks 可供模块hooks 配置选项使用:

Hook描述
prerender:routes使用初始的路由 Set 调用,在预渲染开始前添加或移除条目。
prerender:config使用用于预渲染的内部 Nitro 实例配置调用。
prerender:generate在写入每个路由的文件之前调用,用于检查或修改路由对象(route.contentsroute.fileName……),或设置 route.skip = true
prerender:route每个路由生成后调用。
prerender:done预渲染完成后调用一次,并传入已预渲染和失败路由的列表。

一个常见用例是在运行时动态注册路由,例如从 CMS 或数据库中注册:

nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  modules: [
    (nitro) => {
      nitro.hooks.hook("prerender:routes", async (routes) => {
        const posts = await fetch("https://api.example.com/posts").then((res) => res.json());
        for (const post of posts) {
          routes.add(`/blog/${post.slug}`);
        }
      });
    },
  ],
});

#静态托管

要发布一个不包含服务器包的完全预渲染网站,请使用 staticgithub_pagesgitlab_pages 等静态预设。这些预设会跳过服务器构建、启用 crawlLinks,并且只输出 public 目录,可直接上传到任意静态托管服务。详情请参阅部署文档以及 GitHub Pages 等提供商的文档。

Note

static: true 配置选项只会禁用服务器构建;它本身不会启用预渲染。直接使用该选项而不是静态预设时,请配置 prerender 选项(通常为 crawlLinks: true)来生成页面。