Audit
08-24-2025
13 min read

Nuxt 2 Legacy Audit to Nuxt 3 Modernization Playbook for SaaS Teams

A deep, actionable audit and migration plan for moving Nuxt 2 legacy SaaS apps to Nuxt 3. Covers risk, architecture, code shifts, and a phased rollout.

By Tom Palewski
Nuxt 2 to Nuxt 3 Migration Playbook for SaaS Teams

Nuxt 2 Legacy Audit to Nuxt 3 Modernization Playbook for SaaS Teams

This is a hands-on playbook for senior teams running a legacy Nuxt 2 SaaS and planning a controlled move to Nuxt 3. The goal is not theory. You will get a checklist-driven audit, precise technical decisions, and runnable code patterns that reduce risk and time to cutover.

Assumptions: Node 18 or newer, Nuxt 3 with Vite build, Pinia for state, and modern hosting on Vercel, Netlify, Cloudflare, or a Dockerized VPS. Validate platform specifics before rollout.

Why modernize now

Nuxt 2 is legacy. Security and ecosystem momentum are on Nuxt 3. Teams that postpone migration pay for it with slower delivery, poorer Core Web Vitals, and higher infra bills. The shift is not a rewrite. It is a guided swap of framework plumbing, state management, server routes, and deployment shape anchored by measurable targets.

Pro Tip

If your production build time is above 5 minutes or your P95 Interaction to Next Paint is above 200 ms on mobile, treat modernization as a program, not a backlog ticket. Good INP is 200 ms or less. Poor is above 500 ms. These thresholds are now part of Core Web Vitals. oaicite:0

Business impact

  • Risk and compliance. Sticking with Nuxt 2 increases exposure to unpatched issues and outdated dependencies. The Vue ecosystem has moved. Pinia is the default state solution and Vuex is in maintenance mode. oaicite:1
  • Conversion and search. Core Web Vitals drive discoverability and conversion. INP replaced FID across the ecosystem and is enforced in Search tooling. If you are not measuring INP, you are flying blind. oaicite:2
  • Infra costs. Poor caching, heavy hydration, and server-bound pages raise unit costs. Nitro route rules and edge presets cut cold starts and reduce origin traffic when used correctly. oaicite:3

Technical breakdown

Architectural targets

  • Rendering strategy by route, not a single global mode. Use route rules to mix SSR for app surfaces, ISR for pricing and marketing, and prerender for docs. This is first-class in Nuxt and Nitro. oaicite:4
  • State on the server by default. Replace Vuex with Pinia and move heavy data loads to useAsyncData or server routes. Pinia is the recommended approach in Vue 3, maintained by the core team. oaicite:5
  • Payload discipline. Payload extraction and analyzer tooling help keep JSON small for prerendered pages. Use them to avoid sending full records when lists would do. oaicite:6
  • Edge-first deploy shape. Nitro presets support Vercel and others with minimal configuration. Use edge caching and ISR where traffic and freshness allow. oaicite:7

Config baseline

      
    

This keeps SSR on product surfaces, schedules ISR for pricing, and fully prerenders content routes. Nitro applies these rules for caching and headers at the server layer. oaicite:8

Server API shape

Nitro server routes replace serverMiddleware. Keep validation at the edge, set strict cache headers where safe, and fail closed on upstream errors.

      
    

Nitro route rules can also act as a reverse proxy for specific patterns. This is useful to hide third-party endpoints and standardize headers. oaicite:9

State management shift

Replace Vuex with Pinia. Keep stores small, move side effects into actions, and type everything.

      
    

Pinia is the recommended solution for Vue 3 and is maintained by the core team. oaicite:10

Middleware and auth

Migrate classic Nuxt 2 middleware to the Nuxt 3 pattern. Keep it synchronous where possible.

      
    

Middleware runs on both server and client and plays well with file system routing. oaicite:11

Audit checklist

Run this before you write any migration code. It reduces surprises during the cutover.

Inventory all routes and assign a rendering mode per URL group. Label SSR, ISR, or prerender with documented reasons.

List all Vuex modules. For each, decide if the data should be server-fetched via useAsyncData, kept in a Pinia store, or moved behind an API route.

Search for legacy serverMiddleware, axios plugin usage, and implicit proxies. Replace with Nitro routes and route rules.

Measure Core Web Vitals on production. Track LCP, CLS, and INP on mobile. Treat INP above 200 ms as a priority issue. oaicite:12

Check payload sizes on prerendered pages. Enable payload extraction and run a payload analyzer to catch oversized JSON blobs early. oaicite:13

Validate deployment preset and edge capabilities on your host. Confirm ISR and caching behavior matches expectations under load. oaicite:14

Review SEO rules. Confirm canonical URLs, redirects, and sitemaps for all dynamic routes after the move.

Set CI targets. Build time under 5 minutes for mid-size apps. Unit and e2e green before feature freeze.

Examples and patterns that unblock teams

Route rules for mixed rendering and headers

      
    

Nuxt and Nitro use these rules to change rendering and to apply caching or proxy behavior at the server layer. oaicite:15

Minimal content-driven page with server data

      
    

This works well with prerendered routes and small payloads when you filter fields. Use payload extraction to keep JSON lean on static routes. oaicite:16

Pitfalls and how to avoid them

Warning

Do not port webpack config from Nuxt 2 into Nuxt 3. Vite is the default build pipeline and most custom webpack tuning is irrelevant or harmful. Start clean and only add what you can measure. oaicite:17

Warning

Avoid a big bang cutover without feature freeze and green CI. Run Nuxt 2 and Nuxt 3 branches in parallel, then route a small slice of real traffic to Nuxt 3 before the final switch.

Playbook for a controlled migration

Phase 1 audit

  • Map every route to an explicit rendering mode. Add notes for why that mode fits business and traffic patterns. Use route rules as the execution path. oaicite:18
  • Build inventory of state modules, plugins, middleware, and server middleware. Tag each item with a target in Nuxt 3.
  • Establish baseline metrics. Production Lighthouse for top 10 pages on mobile, plus RUM for INP, LCP, CLS. Treat anything failing INP good threshold as red. oaicite:19

Phase 2 foundations

  • Create a Nuxt 3 branch with TypeScript strict mode and minimal modules.
  • Add route rules and one Nitro API to validate deploy shape and edge caching. Confirm that ISR behaves as expected in your platform logs. oaicite:20
  • Set up Pinia. Migrate one critical Vuex module end to end to confirm ergonomics and typing. oaicite:21

Phase 3 core surfaces

  • Move authentication, session, and account pages. Validate middleware and cookies on both server and client.
  • Migrate high-traffic routes. Keep SSR for app areas, prerender for content, ISR for frequently updated marketing or pricing. oaicite:22
  • Introduce server routes to lift network work from the browser, then add cache headers on safe endpoints.

Phase 4 performance and payloads

  • Enable payload extraction and run a payload analyzer on any static or ISR pages to control JSON size. Common offenders are list pages that serialize entire content bodies. oaicite:23
  • Split code aggressively where user flows diverge. Audit hydration cost for the dashboard and remove unnecessary client state.
  • Optimize images and fonts. Use modern formats and subsetting. Confirm that font preloads do not regress CLS.

Phase 5 soft launch and cutover

  • Run a canary deployment. Send a small percentage of traffic to Nuxt 3. Watch error rates and RUM.
  • Switch the main routes. Keep Nuxt 2 on life support for a short period.
  • Decommission legacy. Remove dead code, lock down the branch, and promote new CI budgets and performance budgets.

Pro Tip

Keep a runbook and rollback plan written as code owners and shell commands, not tribal knowledge. During cutover, you need procedures you can execute under time pressure.

SEO and performance notes that matter in 2025

  • INP is now a Core Web Vital. Good is 200 ms or less. Fix interaction delays from long tasks, heavy event handlers, and main thread contention before you scale traffic. oaicite:24
  • Route rules enable mixed rendering and cache strategies per path. This is a cleaner way to encode SEO intent than one global SSR mode. oaicite:25
  • Nitro presets integrate with edge platforms and incremental static regeneration. Use ISR for pages that must be fresh but do not need full SSR on every request. oaicite:26
  • Payload extraction helps static and ISR pages load faster, but only when you keep the JSON small. Use analyzer tooling and keep only the fields you render above the fold. oaicite:27
  • File system routing stays, but middleware and plugin APIs differ. Port them the Nuxt 3 way, not via shims. oaicite:28

Risk controls and guardrails

  • Feature freeze before migration week. Only hotfixes pass.
  • CI must be green for test and build, with a performance budget gate.
  • Observability on server routes and cache hit ratios.
  • Documented rollback. If canary error rate rises beyond your threshold for 10 minutes, flip back and investigate.

Frequently asked choices

  • Should we keep a BFF layer or lean on Nitro only. For most SaaS, Nitro routes are enough. If you already have a separate BFF with shared auth and rate limits, keep it and proxy through route rules for a uniform surface. oaicite:29
  • Do we prerender the blog and docs. Yes, prerender by default and audit payload size. Use ISR if content updates frequently. oaicite:30
  • What about state on large dashboards. Start with Pinia but aggressively move fetch logic to server routes with cache control and typed responses. oaicite:31

Final notes

Modernizing from Nuxt 2 to Nuxt 3 is a contained, auditable program. Get the rendering plan right per route, lift data work to the server, measure INP and LCP in production, and use Nitro route rules to encode your performance and SEO intent. Teams that run this playbook ship faster, reduce risk, and cut infra waste without changing their product roadmap.

Share this article:

Get your Nuxt 2 audit

Full code analysis in 48 hours

Comprehensive audit with risk assessment and migration roadmap

Fixed price - no surprises

$499 audit with transparent pricing and no hidden fees

Expert migration guidance

Tailored recommendations for your specific Nuxt 2 codebase

Need technical support or have questions?

Contact support →

Tell us about your project

You can also email us at hello@nunuqs.com