渲染模式

Nuxt 是“一个框架多种形态”:SSR、SSG、ISR、SWR、纯 CSR。通过 routeRules 按路由选择,Nitro 会把你的决定翻译成每个平台的原生能力。

四种模式

SSR(服务端渲染)—— 默认

每次请求都在服务端渲染。适合:

  • 个性化页面(鉴权、账户、购物车)。
  • 随用户或请求变化的内容。
  • 对实时 SEO 有要求的页面。

不用额外配置,你一开始就在这个模式里。

SSG(静态站点生成)—— prerender

构建期渲染,直接发纯 HTML。适合:

  • 营销页、落地页。
  • 已知 slug 的文档、博客。
pnpm build && pnpm preview
# 或者纯静态托管:
pnpm generate

按路由声明:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/about': { prerender: true },
  },
})

nuxt generate 相当于对所有路由开启 prerender,并额外生成 /200.html/404.html 作为 SPA fallback。

ISR(增量静态再生)—— isr

先发缓存 HTML,过期后在后台重新生成。适合:

  • 流量大但内容偶尔更新的页面。
export default defineNuxtConfig({
  routeRules: {
    '/blog/**': { isr: 60 },        // 缓存 60 秒
    '/docs/**': { isr: true },      // 缓存到下次发版
  },
})

平台支持:Vercel、Netlify、Cloudflare(视预设而定)。

SWR(stale-while-revalidate)—— swr

思路跟 ISR 类似,但靠 HTTP 缓存头 / CDN 实现:

routeRules: {
  '/feed': { swr: 30 },             // 30 秒内允许发旧内容
}

纯 CSR —— ssr: false

完全跳过 SSR。适合:

  • 登录后访问的仪表板。
  • 首屏就依赖 window / document 的页面。
routeRules: {
  '/admin/**': { ssr: false },
}

想全站 CSR,全局关掉 SSR:

export default defineNuxtConfig({
  ssr: false,
})

nuxt generate 会得到一个 index.html,由它在客户端启动 Vue —— 经典 SPA。

routeRules —— 决策集中在一起

一条规则可以组合多个关注点:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/blog/**': { swr: 3600, headers: { 'cache-control': 's-maxage=3600' } },
    '/api/public/*': { cache: { maxAge: 300 } },
    '/admin/**': { ssr: false, appMiddleware: 'auth' },
    '/legacy': { redirect: { to: '/new', statusCode: 301 } },
    '/proxy/**': { proxy: 'https://api.example.com/**' },
  },
})

可用 key:prerenderisrswrssrcacheheadersredirectproxynoScriptsappMiddleware。通配符:* 单段、** 多段。

静态托管 vs 混合托管

模式 输出 托管位置
全 SSR .output/server/ + public/ Node、Vercel、Netlify、Cloudflare
全 SSG(nuxt generate 只有 .output/public/ 任意静态托管 + CDN
混合(按路由) 预渲染 + SSR 产物混合 支持 ISR / SWR 的平台
CSR(ssr: false + generate) 静态 index.html + JS bundle 任意静态托管

怎么选?

  • 登录后看板 → SSR(没 SEO 需求可以 ssr: false)。
  • 营销页prerender: true
  • 博客 / 文档 / 目录 → ISR 或 SWR。
  • 自家 API/api/*cache.maxAge(幂等接口)。
  • 重定向 / 代理 → 走 routeRules,别自己写中间件。

易踩的坑

  • noScripts: true 不会发 Nuxt 运行时 JS —— 做纯静态落地页香,交互页面慎用。
  • 按路由 ssr: false 也会在服务端构建外壳,客户端只 hydrate JS。
  • prerender 动态路由需要爬虫提示或显式列表(nitro.prerender.routes)。
  • CDN 边缘场景下把 swr / isr 配上合适的 cache-control,体验会更顺。

每条路由挑一种渲染模式,意图统一写在 routeRules,剩下的交给 Nitro。

渲染模式

Nuxt 是「一個框架多種形態」:SSR、SSG、ISR、SWR、純 CSR。透過 routeRules 按路由選擇,Nitro 會將決定翻譯成各平台的原生能力。

四種模式

SSR(伺服器渲染)—— 預設

每個請求皆於伺服器渲染。適合:

  • 個人化頁面(鑑權、帳戶、購物車)。
  • 隨使用者或請求變化的內容。
  • 對即時 SEO 有要求的頁面。

不需額外設定,初始即為此模式。

SSG(靜態站點生成)—— prerender

建置期渲染,直接傳送純 HTML。適合:

  • 行銷頁、著陸頁。
  • 已知 slug 的文件、部落格。
pnpm build && pnpm preview
# 或純靜態代管:
pnpm generate

按路由宣告:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/about': { prerender: true },
  },
})

nuxt generate 等同於對所有路由開啟 prerender,並額外產生 /200.html/404.html 作為 SPA fallback。

ISR(增量靜態再生)—— isr

先提供快取 HTML,過期後在背景重新產生。適合:

  • 流量高但內容偶爾更新的頁面。
export default defineNuxtConfig({
  routeRules: {
    '/blog/**': { isr: 60 },        // 快取 60 秒
    '/docs/**': { isr: true },      // 快取至下次部署
  },
})

平台支援:Vercel、Netlify、Cloudflare(依預設而定)。

SWR(stale-while-revalidate)—— swr

與 ISR 概念相近,但靠 HTTP 快取標頭/CDN 實作:

routeRules: {
  '/feed': { swr: 30 },             // 30 秒內允許提供舊內容
}

純 CSR —— ssr: false

完全跳過 SSR。適合:

  • 登入後的儀表板。
  • 首屏即依賴 windowdocument 的頁面。
routeRules: {
  '/admin/**': { ssr: false },
}

若整站 CSR,全域關閉 SSR:

export default defineNuxtConfig({
  ssr: false,
})

再執行 nuxt generate 會得到 index.html,由它在客戶端啟動 Vue —— 即經典 SPA。

routeRules —— 決策集中於一處

一條規則可組合多個關注點:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/blog/**': { swr: 3600, headers: { 'cache-control': 's-maxage=3600' } },
    '/api/public/*': { cache: { maxAge: 300 } },
    '/admin/**': { ssr: false, appMiddleware: 'auth' },
    '/legacy': { redirect: { to: '/new', statusCode: 301 } },
    '/proxy/**': { proxy: 'https://api.example.com/**' },
  },
})

可用 key:prerenderisrswrssrcacheheadersredirectproxynoScriptsappMiddleware。萬用字元:* 單段、** 多段。

靜態代管 vs 混合代管

模式 輸出 代管位置
全 SSR .output/server/ + public/ Node、Vercel、Netlify、Cloudflare
全 SSG(nuxt generate .output/public/ 任意靜態代管 + CDN
混合(按路由) 預渲染 + SSR 產物混合 支援 ISR/SWR 的平台
CSR(ssr: false + generate) 靜態 index.html + JS bundle 任意靜態代管

如何抉擇?

  • 登入後儀表板 → SSR(無 SEO 需求可設 ssr: false)。
  • 行銷頁prerender: true
  • 部落格/文件/目錄 → ISR 或 SWR。
  • 自家 API/api/* 搭配 cache.maxAge(冪等端點)。
  • 重定向/代理 → 走 routeRules,勿自行撰寫中介層。

常見陷阱

  • noScripts: true 不會輸出 Nuxt 執行時 JS —— 純靜態著陸頁很好,但互動頁面請慎用。
  • 按路由 ssr: false 仍會於伺服器端建置外殼,客戶端僅 hydrate JS。
  • prerender 動態路由需爬蟲提示或明確清單(nitro.prerender.routes)。
  • CDN 邊緣場景下為 swrisr 配合適當 cache-control,體驗更佳。

每條路由挑一種渲染模式,意圖統一寫於 routeRules,其餘交給 Nitro。

Rendering Modes

Nuxt is one framework with many rendering shapes: SSR, SSG, ISR, SWR, CSR-only. You pick per route via routeRules, and Nitro translates your choice into platform-native behavior.

The four modes

SSR (Server-Side Rendering) — the default

Every request is rendered on the server. Best for:

  • Personalized pages (auth, account, cart).
  • Content that changes by user or request context.
  • Pages where SEO of fresh data matters.

No special config needed — you're already here.

SSG (Static Site Generation) — prerender

Render at build time, serve pure HTML. Best for:

  • Marketing pages, landing pages.
  • Docs and blog posts with known slugs.
pnpm build && pnpm preview
# or for fully static hosting:
pnpm generate

Per-route:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/about': { prerender: true },
  },
})

nuxt generate behaves like nuxt build with prerender: true everywhere, plus emits /200.html and /404.html as SPA fallbacks.

ISR (Incremental Static Regeneration) — isr

Serve cached HTML; regenerate in the background after it goes stale. Best for:

  • High-traffic pages whose content updates occasionally.
export default defineNuxtConfig({
  routeRules: {
    '/blog/**': { isr: 60 },        // 60s cache
    '/docs/**': { isr: true },      // cache until redeploy
  },
})

Platform support: Vercel, Netlify, Cloudflare (via the chosen preset).

SWR (Stale-While-Revalidate) — swr

Similar to ISR but implemented via HTTP cache headers / CDN:

routeRules: {
  '/feed': { swr: 30 },             // serve stale up to 30s
}

CSR-only — ssr: false

Skip SSR entirely for a section. Best for:

  • Dashboards behind auth.
  • Pages that depend on window/document at first paint.
routeRules: {
  '/admin/**': { ssr: false },
}

For a fully CSR app, disable SSR globally:

export default defineNuxtConfig({
  ssr: false,
})

nuxt generate then emits an index.html that boots the Vue app client-side — just like a classic SPA.

routeRules — one place to decide

You can combine concerns on the same rule:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/blog/**': { swr: 3600, headers: { 'cache-control': 's-maxage=3600' } },
    '/api/public/*': { cache: { maxAge: 300 } },
    '/admin/**': { ssr: false, appMiddleware: 'auth' },
    '/legacy': { redirect: { to: '/new', statusCode: 301 } },
    '/proxy/**': { proxy: 'https://api.example.com/**' },
  },
})

Available keys include prerender, isr, swr, ssr, cache, headers, redirect, proxy, noScripts, appMiddleware. Wildcards: * for segments, ** for deep matches.

Static vs hybrid hosting

Mode Output Hosting
Full SSR .output/server/ + public/ Node, Vercel, Netlify, Cloudflare
Full SSG (nuxt generate) .output/public/ only Any static host + CDN
Hybrid (per-route) Mix of prerendered + SSR artefacts Platforms that understand ISR/SWR
CSR (ssr: false + generate) Static index.html + JS bundles Any static host

When to choose what

  • Logged-in dashboards → SSR (or ssr: false if you really don't need SEO).
  • Marketing pagesprerender: true.
  • Blog / docs / catalogs → ISR or SWR.
  • APIs for your app/api/* with cache.maxAge if idempotent.
  • Redirects / proxiesrouteRules, not custom middleware.

Gotchas

  • noScripts: true emits HTML without Nuxt's runtime JS — great for pure static landing pages, fatal for interactive ones.
  • ssr: false per route still builds the shell on the server; the client hydrates only JS.
  • prerender dynamic routes require crawler hints or an explicit list (nuxt.confignitro.prerender.routes).
  • On CDN edges, combine swr/isr with cache-control headers to keep things snappy.

Pick rendering mode per route, keep your intent in routeRules, and let Nitro handle the rest.