Nuxt Route Rules for Hybrid Rendering

This guide is part of Vue & Nuxt Performance, within Framework Performance. By default, a Nuxt app server-renders every route on every request. That is flexible but wasteful: a pricing page that changes monthly, a blog post that never changes, and a product page that changes hourly all pay the full cost of rendering per request, and users pay it in TTFB. Route rules let you choose per route pattern: prerender at build time, cache with stale-while-revalidate, regenerate incrementally, render only on the client, or keep full SSR — along with headers, redirects and CORS.

Choosing well is the single largest TTFB lever in most Nuxt apps. Static and cached routes are served from the CDN or Nitro's cache in milliseconds; only routes that truly need per-request rendering pay for it.

TTFB p75 by route rule (same blog post template) Bar chart comparing TTFB at the 75th percentile for a blog post served with different Nuxt route rules. TTFB p75 by route rule (same blog post template) SSR every request 640ms swr: 3600 (Nitro cache) 140ms prerender: true (CDN) 60ms

Rapid Diagnosis

  • List routes and how often their content changes: build-time, hourly, per request, per user.
  • Check current rendering: are all routes SSR on every request?
  • Check TTFB per route in the field.
  • Check hosting: whether the platform supports Nitro's cache, ISR or CDN caching for route rules.

Root Cause Analysis

1. Default SSR everywhere. Every request renders.

2. No caching of rendered HTML. Even unchanged pages are rebuilt.

3. Personalisation assumptions. Pages treated as personalised when only a small part is.

4. Dashboards rendered on the server. Private, interactive pages with no SEO need incur SSR cost.

Step-by-Step Resolution

1. Define route rules

javascript
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/pricing': { prerender: true },
    '/blog/**': { swr: 3600 },                    // cached, revalidated hourly in the background
    '/products/**': { swr: 600 },
    '/search': { swr: 60 },
    '/account/**': { ssr: false },                // client-only dashboard
    '/api/catalog/**': { cache: { maxAge: 300 } },
  },
});
// trade-off: SWR serves possibly stale content for up to the TTL; choose TTLs per
// route based on how quickly changes must appear.

2. Separate personal parts from cacheable pages

Render shared content in cached routes and fetch personal parts (cart count, greeting) on the client after hydration, so the route itself can be cached.

3. Match rules to hosting

On platforms with ISR support, isr uses the platform's CDN caching; on Node servers, swr uses Nitro's cache storage. Check the deployment preset's documentation.

4. Purge or revalidate on content changes

Trigger rebuilds or cache invalidation from the CMS when content changes, so long TTLs do not mean stale content.

Choosing a route rule Decision sequence for selecting a Nuxt route rule for a route. Choosing a route rule Does content change only on deploy? prerender: true yes no Is content shared but updated over time? swr or isr with a TTL yes no Is the page private and interactive, without SEO needs? ssr: false yes no SSR per request (keep it fast, stream if possible)

Verification

Check response headers and timing for each route type: prerendered pages served statically, SWR routes showing cache hits after the first request, client-only routes returning a shell. Measure TTFB per route in the field. Verify freshness: update content and confirm it appears within the expected time.

Worked Example: A Software Vendor's Website

A software vendor's Nuxt site served marketing pages, docs, a blog, a changelog and a customer portal — all SSR on every request from a single-region Node server. TTFB p75 was 700ms globally. The team prerendered marketing pages, cached docs and blog with swr: 3600 (with a CMS webhook to purge on publish), cached the changelog for 10 minutes, and made the customer portal client-only. TTFB p75 for public pages fell to 90ms, server CPU dropped by 85%, and LCP p75 improved from 2.6 to 1.5 seconds. The portal's LCP was unchanged, but its server load disappeared.

Hybrid Rendering and Personalisation

Many pages that seem personalised are mostly shared: a product page with a personalised price for logged-in users, a homepage with a greeting. Cache the shared page and fetch personal data client-side (with skeleton placeholders sized to avoid CLS), or use edge logic to vary the cache by a small set of segments (currency, country). This keeps pages cacheable while still showing personal content. Avoid varying the cache by session cookie, which destroys the hit rate.

Monitoring Cache Effectiveness

Route rules only help if the cache is hit. Expose a cache status (for example, a Server-Timing entry or response header added by the platform) and track hit ratio per route group. Low hit ratios on SWR routes usually mean the cache key varies too much (query parameters, cookies) or TTLs are too short for the traffic level. Pages with little traffic will miss more often; prerendering popular ones at build time and using SWR for the rest balances build time and freshness.

Route rule options at a glance The main Nuxt route rule options and what they do. Route rule options at a glance Option Where HTML comes from Freshness prerender: true build output (static) until next deploy swr: N Nitro cache refreshed in background after N s isr: N platform CDN cache refreshed after N s ssr: false client renders a shell always live data default SSR rendered per request always fresh

Rolling Out Route Rules

Introduce route rules gradually, starting with the routes whose content changes least: legal pages, marketing pages and documentation. Prerender them and confirm they deploy correctly. Next, add SWR caching to blog and product routes with a conservative TTL and a purge mechanism, and watch for stale-content reports. Finally, consider client-only rendering for private areas. Keep the route rules file commented with the reason for each rule, since future changes to content or personalisation may require revisiting them. Review the rules whenever a new section of the site is added.

Common Mistakes

  • SSR for static pages. Wasted server time and slower TTFB.
  • Caching personalised pages. Users see each other's data.
  • Very long TTLs without purging. Content changes take hours to appear.
  • Client-only rendering for public pages. Hurts LCP and SEO.

Edge Cases

Prerendering many pages. Large sites may prefer SWR for low-traffic pages to keep builds fast.

Query parameters. Decide whether cached routes vary by query; normalise or ignore irrelevant parameters.

Preview mode. Bypass caches for editors previewing unpublished content.

API caching. Cache API routes used by many pages, which also speeds up client navigations.

FAQ

What are Nuxt route rules?

A configuration object mapping route patterns to rendering and caching options, headers, redirects and more.

What is the difference between swr and isr?

Both cache rendered pages and refresh them. swr uses Nitro's cache (server storage); isr relies on platform CDN support where available.

Does ssr: false hurt SEO?

Yes for public pages, because the initial HTML lacks content. Use it for private, app-like routes.

Can I prerender dynamic routes?

Yes, by listing them or letting the crawler discover links at build time. For very many pages, combine with SWR.

How do I invalidate cached routes?

Redeploy for prerendered routes, or clear Nitro's cache storage or the platform cache for SWR/ISR routes, often from a CMS webhook.

Do route rules affect client-side navigation?

They affect what the server returns. Client navigations fetch payloads, which can be cached and prerendered too.

Can route rules set cache headers?

Yes, with the headers option, for example to add Cache-Control for static assets or API routes.

Should every page be prerendered?

Only if content is known at build time and builds stay fast. Use SWR or ISR for frequently updated or very numerous pages.

Can route rules apply to API routes?

Yes. Cache rules on server API routes speed up both server rendering and client-side data fetching.

Do route rules work with static hosting?

Prerendered routes do. SWR and server rendering need a server or a platform that supports Nitro's server output.