预渲染
在构建时渲染路由,并将其作为静态资源提供
启用预渲染后,Nitro 会在构建期间获取指定路由,并将响应写入 .output/public 目录。预渲染的路由随后会作为静态文件提供。请求时不会进行服务器渲染,因此这些路由速度快、可缓存,并且可以部署到任意静态托管服务或 CDN。
预渲染适用于内容不会随请求变化的路由:落地页、文档、博客文章,或输出内容固定的 JSON 端点。动态路由仍然可以继续由服务器提供,并且你可以在同一个应用中自由混合预渲染路由和服务器渲染路由。
#预渲染路由
#prerender.routes 配置
使用 prerender.routes 选项列出要预渲染的路由:
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 路由规则将路由标记为预渲染:
import { defineConfig } from "nitro";
export default defineConfig({
routeRules: {
"/about": { prerender: true },
},
});Warning
路由规则只会将完全匹配的路径添加到预渲染列表中。像 "/blog/**": { prerender: true } 这样的通配符模式不会自动展开,因为 Nitro 无法知道哪些路由与该模式匹配。要预渲染一组动态路由,请使用链接爬取或 prerender:routes hook。
#爬取链接
除了(或作为补充)列出每个路由之外,还可以启用 crawlLinks,让 Nitro 通过跟随预渲染 HTML 页面中的链接来发现路由:
import { defineConfig } from "nitro";
export default defineConfig({
prerender: {
crawlLinks: true,
routes: ["/"],
},
});爬虫会从每个预渲染 HTML 页面中提取 href 属性,并将发现的路由加入预渲染队列。外部链接、哈希链接,以及指向带扩展名文件的链接(.json 除外)都会被跳过。相对链接会根据其所在页面进行解析。
如果启用了 crawlLinks 且未指定路由,爬取会从 / 开始。
Tip
处理程序可以通过将 x-nitro-prerender 响应标头设置为以逗号分隔的路径列表,来为预渲染添加其他路由。即使禁用了 crawlLinks,此功能仍然有效。
#忽略路由
使用 prerender.ignore 跳过路由。每个条目可以是字符串前缀、正则表达式,或接收路径的函数:
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 路由规则排除路由。与启用预渲染不同,通配符模式可以用于排除,因为它们会针对每个候选路由进行匹配:
import { defineConfig } from "nitro";
export default defineConfig({
routeRules: {
"/dynamic/**": { prerender: false },
},
});#公共资源
由带有基础 URL 前缀的公共资源提供的路由始终会被跳过。此外,你可以设置 prerender.ignoreUnprefixedPublicAssets: true,跳过已经由不带前缀的公共资源提供的路由,从而避免输出中出现重复文件:
import { defineConfig } from "nitro";
export default defineConfig({
prerender: {
crawlLinks: true,
ignoreUnprefixedPublicAssets: true,
},
});#选项
| 选项 | 默认值 | 描述 |
|---|---|---|
failOnError | false | 当路由无法预渲染时使构建失败。适用于 CI。 |
retry | 3 | 失败路由的重试次数。传入 Infinity 可无限重试。 |
retryDelay | 500 | 每次重试之间的延迟时间,单位为毫秒。 |
concurrency | 1 | 并行预渲染的最大路由数。 |
interval | 0 | 预渲染请求之间的延迟时间,单位为毫秒。 |
autoSubfolderIndex | true | 将 HTML 路由写入子文件夹索引文件。 |
Note
retry 和 retryDelay 选项可以在配置中接受,但当前的 v3 预渲染器尚未应用它们。
concurrency 和 interval 选项控制预渲染速度。提高 concurrency 可以加快大型网站的速度,或者添加 interval,以避免路由调用外部 API 时触发速率限制。
autoSubfolderIndex 控制 HTML 文件写入 .output/public 的方式:
# autoSubfolderIndex: true (default)
/about -> .output/public/about/index.html
# autoSubfolderIndex: false
/about -> .output/public/about.html当你的托管服务提供商不允许配置尾部斜杠行为时,将其设置为 false。
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.contents、route.fileName……),或设置 route.skip = true。 |
prerender:route | 每个路由生成后调用。 |
prerender:done | 预渲染完成后调用一次,并传入已预渲染和失败路由的列表。 |
一个常见用例是在运行时动态注册路由,例如从 CMS 或数据库中注册:
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}`);
}
});
},
],
});#静态托管
要发布一个不包含服务器包的完全预渲染网站,请使用 static、github_pages 或 gitlab_pages 等静态预设。这些预设会跳过服务器构建、启用 crawlLinks,并且只输出 public 目录,可直接上传到任意静态托管服务。详情请参阅部署文档以及 GitHub Pages 等提供商的文档。
Note
static: true 配置选项只会禁用服务器构建;它本身不会启用预渲染。直接使用该选项而不是静态预设时,请配置 prerender 选项(通常为 crawlLinks: true)来生成页面。