Nitro Renderer
使用 renderer 通过自定义 HTML 或模板系统处理所有未匹配的路由。
Nitro v3 Alpha 文档仍在开发中——可能会有更新、不完善的地方和偶尔的不准确信息。
renderer 是 Nitro 中的一个特殊 handler,它捕获所有不匹配任何特定 API 或 route handler 的路由。它通常用于服务器端渲染(SSR)、提供单页应用(SPA)或创建自定义 HTML 响应。
HTML 模板
自动检测的 index.html
默认情况下,Nitro 会自动在项目 src 目录中查找 index.html 文件。
如果找到,Nitro 将使用它作为 renderer 模板,并为所有未匹配的路由提供服务。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>我的 Vite + Nitro 应用</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
import { defineHandler } from "nitro/h3";
export default defineHandler((event) => {
return { hello: "API" };
});
当检测到
index.html 时,Nitro 会在终端中自动记录:Using index.html as renderer template.使用此设置:
/api/hello→ 由你的 API routes 处理/about、/contact等 → 使用index.html提供服务
自定义 HTML 文件
你可以使用 Nitro 配置中的 renderer.template 选项指定自定义 HTML 模板文件。
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
renderer: {
template: './app.html'
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>自定义模板</title>
</head>
<body>
<div id="root">加载中...</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
超文本预处理器(实验性)
Nitro 使用 rendu 超文本预处理器,它提供了一种简单而强大的方式来创建带有 JavaScript 表达式的动态 HTML 模板。
你可以使用特殊的分隔符来注入动态内容:
{{ content }}输出 HTML 转义的内容{{{ content }}}或<?= expression ?>输出原始(未转义)内容<? ... ?>用于 JavaScript 控制流
它还暴露了全局变量:
$REQUEST:传入的 Request 对象$METHOD:HTTP 方法(GET、POST 等)$URL:请求 URL 对象$HEADERS:请求头$RESPONSE:响应配置对象$COOKIES:包含请求 cookies 的只读对象
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>动态模板</title>
</head>
<body>
<h1>Hello {{ $REQUEST.url }}</h1>
</body>
</html>
自定义 renderer handler
对于更复杂的场景,你可以创建自定义 renderer handler,以编程方式生成响应。
创建 renderer 文件并使用 defineRenderHandler 定义自定义渲染逻辑:
renderer.ts
import { defineRenderHandler } from "nitro/runtime";
export default defineRenderHandler((event) => {
return {
body: `<!DOCTYPE html>
<html>
<head>
<title>自定义 Renderer</title>
</head>
<body>
<h1>来自自定义 renderer 的问候!</h1>
<p>当前路径:${event.path}</p>
</body>
</html>`,
headers: {
'content-type': 'text/html; charset=utf-8'
}
}
})
然后,在 Nitro 配置中指定 renderer 入口:
nitro.config.ts
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
renderer: {
entry: './renderer.ts'
}
})
Renderer 优先级
renderer 始终作为 catch-all 路由(/**)并具有最低优先级。这意味着:
首先匹配特定的 API routes(例如 /api/users)
接下来匹配特定的 server routes(例如 /about)
renderer 捕获其他所有内容
api/
users.ts → /api/users (首先匹配)
routes/
about.ts → /about (其次匹配)
renderer.ts → /** (捕获所有其他路由)
如果你在 routes 中定义了 catch-all 路由(
[...].ts),Nitro 会警告你 renderer 将覆盖它。使用更具体的路由或不同的 HTTP 方法来避免冲突。使用场景
单页应用(SPA)
为所有路由提供你的 SPA 的 index.html 以启用客户端路由:
这是 Nitro 与 Vite 一起使用时的默认行为。