路由规则
通过 routeRules 配置不同路由的渲染策略、缓存、重定向等行为。
为什么需要路由规则?
同一个项目中,不同页面可能有完全不同的需求:
| 页面 | 需求 |
|---|---|
| 首页 | 需要 SEO + 缓存(内容不常变) |
| 管理后台 | 不需要 SEO,用 CSR 就行 |
| API 接口 | 需要跨域 |
| 旧 URL | 需要重定向到新 URL |
| 关于页面 | 完全静态,构建时预渲染就行 |
routeRules 让你为不同路由配置不同策略,而不需要修改代码。
基本配置
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { swr: 3600 }, // 首页缓存 1 小时
'/blog/**': { isr: 60 }, // 博客 ISR 60秒
'/admin/**': { ssr: false }, // 后台 CSR
'/api/**': { cors: true }, // API 跨域
'/old-page': { redirect: '/new-page' }, // 重定向
'/about': { prerender: true }, // 预渲染
'/secure/**': { // 安全头
headers: {
'X-Frame-Options': 'DENY',
},
},
},
})`
通配符**:匹配多级路径。如/blog/**匹配/blog/a、/blog/a/b/c` 等。
规则选项详解
ssr — 控制渲染模式
routeRules: {
'/admin/**': { ssr: false }, // 后台用 CSR
'/blog/**': { ssr: true }, // 博客用 SSR
}为什么后台用 CSR?
管理后台不需要 SEO,而且后台通常有很多交互。CSR 模式下,服务器不用渲染 HTML,响应更快。
swr — Stale-While-Revalidate
返回缓存内容,同时在后台重新验证:
routeRules: {
'/': { swr: 3600 }, // 缓存 1 小时
'/static/**': { swr: true }, // 永久缓存
'/api/live/**': { swr: false }, // 不缓存
}SWR 的工作原理
- 首次请求:服务端渲染页面,缓存结果
- 后续请求(缓存期内):直接返回缓存,同时在后台重新渲染
- 下次请求:返回最新渲染的结果
用户体验
永远能快速看到内容(即使是缓存的),同时数据保持新鲜。
适合 SWR 的页面
首页、列表页——需要快速响应,内容偶尔更新。
isr — Incremental Static Regeneration
增量静态再生,适合内容不太频繁变化的页面:
routeRules: {
'/blog/**': { isr: 60 }, // 每 60 秒重新生成
'/about': { isr: true }, // 永不重新生成(静态)
'/admin/**': { isr: false }, // 禁用 ISR
}ISR vs SWR 的区别
| 特性 | SWR | ISR |
|---|---|---|
| 返回策略 | 先返回旧缓存,后台更新 | 缓存过期后才重新生成 |
| 用户体验 | 总是快速响应 | 过期后可能短暂等待 |
| 适合 | 需要极快响应的页面 | 可以容忍短暂过期的页面 |
INFO
️ ISR 需要部署在支持持久化存储的平台(如 Node.js、Vercel) 纯静态部署不支持 ISR
prerender — 预渲染
构建时生成静态 HTML:
routeRules: {
'/about': { prerender: true },
'/pricing': { prerender: true },
}预渲染 vs ISR vs SWR
prerender:构建时一次性生成,最简单isr:运行时按需生成 + 定期更新swr:运行时按需生成 + 缓存 + 后台更新
选择建议
内容几乎不变 → prerender;偶尔更新 → isr;需要快速响应 → swr。
redirect — 重定向
routeRules: {
'/old-page': { redirect: '/new-page' }, // 302 临时
'/old-blog/**': { redirect: '/blog/**', statusCode: 301 }, // 301 永久
}301 vs 302
301(永久重定向):搜索引擎会把权重转移到新 URL302(临时重定向):搜索引擎仍保留旧 URL
SEO 建议
如果旧 URL 永远不再使用,用 301;如果只是临时重定向,用 302。
cors — 跨域
routeRules: {
'/api/**': { cors: true },
}等价于添加以下响应头:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: *什么时候需要?
如果你的 API 需要被其他域名的网站访问(如第三方调用、嵌入式组件)。
INFO
️ 安全提醒:cors: true 允许任何域名访问 生产环境中,建议在 Nitro 中间件中精确控制允许的来源
headers — 自定义响应头
routeRules: {
'/assets/**': {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable',
},
},
'/secure/**': {
headers: {
'X-Frame-Options': 'DENY',
'X-Content-Type-Options': 'nosniff',
},
},
}常用安全头
X-Frame-Options: DENY— 禁止被 iframe 嵌入X-Content-Type-Options: nosniff— 防止 MIME 类型嗅探Content-Security-Policy— 内容安全策略
规则优先级
更具体的规则优先级更高:
routeRules: {
'/blog/**': { swr: 3600 }, // 所有博客缓存 1 小时
'/blog/latest': { swr: 60 }, // 最新文章缓存 1 分钟(优先级更高)
}优先级规则
- 精确路径(如
/blog/latest)> 通配路径(如/blog/**) - 更长的路径 > 更短的路径
- 同级别按配置顺序
动态路由规则
使用 defineRouteRules 在页面中动态定义:
<script setup>
// 只能在页面中使用
defineRouteRules({
swr: 3600,
})
</script>与 nuxt.config.ts 中的 routeRules 区别
nuxt.config.ts:全局配置,所有路由集中管理defineRouteRules:页面级配置,和页面代码在一起
推荐
大多数情况用 nuxt.config.ts 集中管理。只有页面特有的规则才用 defineRouteRules。
完整示例
export default defineNuxtConfig({
routeRules: {
// 首页:SSR + 缓存
'/': { swr: 3600 },
// 博客:ISR
'/blog/**': { isr: 60 },
// 后台:CSR
'/admin/**': { ssr: false },
// API:跨域
'/api/**': { cors: true },
// 静态资源:长缓存
'/_nuxt/**': {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable',
},
},
// 旧页面重定向
'/old-url': { redirect: '/new-url' },
// 预渲染
'/sitemap.xml': { prerender: true },
},
})知识脉络
路由守卫 → 你在这里:路由规则
│
├─→ 下一步:页面元信息
│
└─→ 相关:渲染模式(03-核心概念)