Engagements - Next.js App Router migration for a production app, route by route, with no code freeze

A Next.js App Router migration is not a weekend refactor once real money runs through the app. You have indexed URLs that cannot move, sessions that cannot drop, a checkout that cannot break, and analytics your reporting depends on. The official docs explain the syntax. They do not inventory your routes, decide the rendering mode for each one, or test your payment flow before the merge. This build takes the whole legacy Next.js migration off your team for four to eight weeks and ships it in weekly PRs your engineers review.

Start next week4–8 weeks typical
  • SaaS founders
  • Marketplaces
  • Product teams
  • Agencies

What you'll have at launch

Your production app on the App Router with the same URLs, the same logins, and the same checkout, migrated route by route with nothing frozen and every risky route regression-tested before it merges.

  • Your app on the App Router, with Pages and App Router coexisting cleanly through the transition and no big-bang cutover day.
  • Every indexed URL still resolving at the same address, or 301ing to its replacement, with canonical tags and the sitemap checked against the pre-migration route inventory.
  • Auth, sessions, checkout, and forms regression-tested route by route, so the flows that earn revenue behave the same after the migration as before it.
  • The rendering strategy right per route: SSR for dashboards, SSG for marketing, ISR for content, instead of everything pushed to the client.
  • Hydration mismatches and caching bugs fixed rather than papered over, and Core Web Vitals back in the green on the routes that rank.

How we build it

A build runs 4–8 weeks typical, shipped week by week in increments you review and merge.

  1. Week 1 · Route inventory and audit

    Every route gets listed with its data fetching, rendering mode, auth requirement, and search traffic. That inventory becomes the migration order and the URL map we check the whole build against, so nothing indexed gets migrated by accident and the revenue routes go last, once the pattern is proven.

  2. Weeks 2–3 · Prove the pattern on low-risk routes

    Pages and App Router start running side by side and a few low-traffic routes migrate end to end: layouts, server and client boundaries, data fetching moved off the client, caching and revalidation tags set deliberately. You finish this phase with a repeatable playbook your team can read in a PR, and zero routes frozen.

  3. Weeks 4–6 · Migrate the routes that earn

    Dashboards, auth, checkout, and forms move in priority order, one weekly PR at a time. Each one carries its own regression check on the flow it touches, so a session, a payment, or a form submission gets exercised before the merge rather than discovered broken by a customer.

  4. Weeks 7–8 · Cutover, redirects, and deploy verification

    The last routes move, the Pages Router scaffolding comes out, and we verify the migration against the week one inventory: redirects resolving, canonicals correct, sitemap and robots intact, analytics and conversion events still firing, Core Web Vitals measured on the routes that rank.

What's included

  • A route inventory of the whole app before anything moves: rendering mode, data fetching, auth requirement, and search traffic per route, which sets the migration order.
  • SEO URL preservation as a hard constraint. Indexed paths keep their addresses or get 301s, and canonical tags, the sitemap, and robots rules are checked against the inventory at cutover.
  • Incremental migration with Pages and App Router side by side, so the app keeps shipping features and nothing freezes for the duration.
  • Server and client boundary cleanup: data fetching moved to the server, Server Components, server actions, and route handlers wired properly, and secrets kept out of the client bundle.
  • Auth and session checks on every protected route, so middleware, cookies, and redirects after login behave the same on the App Router as they did on Pages.
  • Checkout, billing, and form regression tests on the flows that earn, run before the PR merges rather than after a customer finds the bug.
  • Analytics and tracking verified after each batch: page views, conversion events, and consent behaviour, because the App Router changes when and where they fire.
  • Deploy verification on every batch, plus a Core Web Vitals pass. Bundle trimming, LCP, CLS, and INP fixes on the routes that rank.
  • Clean PRs matched to your conventions, reviewed and merged by your team. No black-box rewrite dropped on you at the end.

What a build like this looks like

Scopes we've shaped this engagement around. Yours is one of them, or close enough that week one settles it.

  • A SaaS app with a marketing site attached. The marketing pages rank and the app behind the login pays the bills, and both live in one Next.js repo. The migration splits them properly: static or ISR for the pages Google indexes, server-rendered for the authenticated app, with the pricing and signup URLs untouched and the session flow tested on every protected route.
  • A marketplace with listing and search pages. Thousands of listing URLs carry your organic traffic and your filters run on the client. Moving them to server rendering with correct revalidation tags is where marketplace migrations usually break. Here the listing URLs stay put, search and filters get server-side data fetching, and the seller dashboard migrates behind them.
  • A customer-facing dashboard on legacy data fetching. Every chart calls the API from a client component and the dashboard takes seconds to paint. The migration moves the queries server-side with Suspense and streaming, keeps role-based access intact through the boundary change, and gets first paint down without rewriting the product.
  • A content-heavy site on the Pages Router. Hundreds of articles or docs pages built with getStaticProps, and a rebuild you cannot afford to have deindex you. The route inventory becomes the URL map, ISR with on-demand revalidation replaces the old static build, and canonicals, redirects, and the sitemap get verified page group by page group.
  • A half-finished migration someone else started. Some routes are on the App Router, some are not, and nobody wants to touch either. We audit what exists, stabilise the routes already moved, re-establish one clean pattern, then continue in order. Inheriting a stalled migration is a normal starting point.

Stack

  • Next.js
  • React
  • TypeScript
  • Vercel

How this build lowers your risk

  • Search traffic is a constraint, not an afterthought. The week one route inventory records every indexed URL, and cutover checks the live app against it: redirects, canonicals, sitemap, robots. Migrations that quietly drop rankings do it by moving or breaking URLs nobody wrote down first.
  • The flows that earn get tested before they merge. Auth, checkout, and forms are the routes where an App Router mistake costs real money. They migrate late, after the pattern is proven on low-risk routes, and each carries a regression check on the flow it touches so problems surface in review.
  • Nothing freezes and you can stop at any point. Both routers run side by side and every route lands independently, so your team keeps shipping features and the app is deployable every week. If priorities change in week five, you pause on a working app rather than a half-migrated one.
  • No contract and no lump-sum quote. It runs on the flat monthly subscription with multiple plans available. You pay for the active weeks, reorder which routes go first whenever you like, and pause between batches. Every migrated route is in your repo as it lands, so leaving is never a hostage negotiation.

Migration build vs the docs, a codemod, or an agency

Four honest ways to get onto the App Router. If your app is small and nothing indexed is at stake, the docs route is cheaper and we will say so. The build exists for apps where a broken URL or a broken checkout costs more than the migration.

OptionBest whenWhere it stops
The official Next.js migration guide, in-houseYou have spare senior capacity, a small route count, and no revenue flow that a mistake would interrupt. The guide is accurate and free, and for a straightforward app it is the right call.It teaches syntax and the new conventions. It does not inventory your routes, decide rendering per route, preserve your indexed URLs, or test your checkout, and in-house migrations stall because feature work always outranks them.
Codemods and migration templatesThe mechanical part: moving files, rewriting imports, converting data-fetching signatures on routes that are simple enough for a script to handle.A codemod cannot decide that your dashboard should stream and your pricing page should be static, and it will not notice a dropped session, a lost redirect, or an analytics event that stopped firing.
Next.js App Router migration build (this page)A production app where indexed URLs, auth, checkout, and analytics all have to survive. Route inventory first, revenue routes migrated last with regression checks, redirects and deploy verified at cutover.It is a month-plus engagement by design, so it is the wrong shape for a single route conversion or a one-off hydration bug.
Legacy app rebuildThe Next.js version is ancient, the data layer is tangled, and migrating the routes would mean carrying years of decisions you already regret across.A rebuild is longer and touches more than routing, so if the app is fundamentally sound the migration is the cheaper answer.
Ongoing Next.js work in task modeThe migration is done and the app now generates a steady trickle of Next.js work: a slow route, a caching bug, a new server action.Task mode moves one small thing at a time, so a whole migration still wants a build's dedicated weeks.

Is this the right build for you?

A good fit when

  • You run a real Next.js app on the Pages Router with users, revenue, or search traffic that a bad migration would damage.
  • Your team cannot spare the weeks a migration takes, or has started one and stalled somewhere in the middle.
  • You want one senior engineer owning the migration for a month or more, shipping weekly PRs your engineers review and merge.
  • Compiling is the easy part. The migration has to survive contact with auth, checkout, redirects, and analytics.

Not a fit when

  • You want a handful of files converted or a single hydration bug fixed. A build is a month-plus engagement by design.
  • The app is small, new, and has no indexed URLs or payment flow, in which case the official Next.js migration guide plus a codemod may genuinely be enough.
  • The codebase is far enough gone that migrating it is the wrong move and a rebuild is the honest answer. That is the legacy app rebuild.
  • You want the migration done invisibly with no review from your side. Everything here ships as PRs your team merges.

How it runs on the subscription

A Next.js migration service that works is weeks of careful incremental work, the opposite of a task, so it runs as a build: the board dedicated to moving your app across, shipping migrated routes every week. We match the monthly plan to the workload, and most App Router migrations land in four to eight weeks. Because it is incremental you can pause between batches and reorder which routes go first whenever the roadmap demands it. After cutover the same subscription flips to task mode for the ongoing Next.js work a live app generates.

Frequently asked questions

Do you have to freeze our app during the Next.js App Router migration?
No, and that is the point of doing it route by route. Pages and App Router run side by side, each route migrates independently, and every batch ships as a PR your team merges. Your engineers keep shipping features the whole time, there is no multi-week freeze, and there is no single terrifying cutover day.
Will we lose search rankings during the migration?
Not if the URLs are treated as a constraint from week one. The route inventory records every indexed path before anything moves, so each one either keeps its address or gets a 301 to its replacement. At cutover we check redirects, canonical tags, the sitemap, and robots rules against that inventory on the live deploy. Ranking drops in these migrations almost always trace back to URLs nobody wrote down first.
How do you keep auth and checkout from breaking?
They migrate late and they migrate with tests. The pattern gets proven on low-traffic routes first, then middleware, sessions, and login redirects move with checks on each protected route, and checkout and form flows get exercised before the PR merges. Server and client boundaries change in an App Router migration, which is exactly why payment and session flows deserve a regression check rather than a hopeful deploy.
Our migration is already half-finished and broken. Can you take it over?
Yes, that is common. We audit what is already moved, stabilise those routes, re-establish one clean pattern, then continue in inventory order from there. Inheriting a stalled legacy Next.js migration is a normal starting point rather than a problem.
Why not just follow the official Next.js docs ourselves?
For a small app with no indexed URLs and no payment flow, do that. The guide is accurate and free. The docs cover syntax and conventions, though, not your route inventory, your rendering decisions per route, your redirect map, or whether your analytics still fire afterwards. That production risk, plus the fact that in-house migrations lose every week to feature work, is what this build is for.
Are you a Next.js App Router migration agency?
No. An agency wraps the work in a project manager, a rotating team, and a lump-sum quote. This is one senior engineer who works in Server Components daily, running your migration on a flat monthly subscription with no contract. You get weekly PRs into your own repo instead of a status deck.
How long does an App Router migration take?
Most take four to eight weeks, depending on route count and how much the app leans on client-side data fetching and old caching assumptions. Because it is incremental you see migrated routes landing every week rather than waiting for one big finish, and you can pause between batches without leaving the app in a broken state.
Who reviews the changes?
Your team does. Everything ships as PRs into your repo, matched to your conventions, and your engineers review and merge each one. Nothing arrives as an opaque rewrite. You watch the migration happen route by route.

Got a project? Let's ship it.

3 spots open. Tell us what you need shipped. We'll agree how the work will run and give each active item a clear target. Larger requests stay visible while smaller subtasks move toward done.