App Router Migration
Page-by-page migration of production Next.js apps from Pages Router. ISR semantics tested end-to-end; third-party libraries audited for RSC compatibility before commit.
We ship production Next.js — App Router, server components, streaming, ISR — and we have migrated real sites from Pages Router (including the one you are reading).
NerdHeadz has moved real Next.js sites from Pages Router to App Router — marketing surfaces, full SaaS apps, the friction in the middle. This page is the honest version of what worked, what did not, and when we tell clients to wait. We have shipped server components for content-heavy pages, streaming for slow data fetches, ISR with the new revalidate semantics, route handlers, and the deployment patterns that make Vercel and Cloudflare both work in practice. Pages Router still has its place — apps with heavy client-side state, projects pinned to libraries that have not caught up to React Server Components. The migration is worth it when there is a concrete win at stake. The rest of this page is what we tell a CTO over coffee.

Page-by-page App Router migration is the work, not the slogan. Server components where they earn their place. ISR with surgical revalidation. The framework decision behind every web build we ship.
Page-by-page migration of production Next.js apps from Pages Router. ISR semantics tested end-to-end; third-party libraries audited for RSC compatibility before commit.
Move data-fetching to the server. Smaller client bundles, secrets that never reach the browser, and a clean RSC/client-component boundary that does not fight you at runtime.
revalidate exports plus revalidateTag and revalidatePath for surgical cache invalidation. Marketing pages stay static; dashboards rebuild on demand.
Route handlers running at the edge for low-latency public APIs. Global response times measured in tens of milliseconds.
Single TypeScript SDK consumed by backend, web, and mobile. Schema drift becomes a compile-time error.
On a content-heavy marketing site we migrated last year, App Router cut Time-to-First-Byte by removing the round-trip to a client-side data fetcher — the page rendered server-side with the data already in place, no loading shimmer for users, no extra hop for crawlers. On a separate internal product, App Router let us stream the slowest part of the page (a third-party API call that took roughly 2.4 seconds) while the rest rendered immediately. The wins are concrete, not abstract: fewer client bundles, less hydration work, server-only secrets that never reach the browser, and the option to run database queries inside React components instead of bouncing through an API route. The site you are reading is one of those deployments.

Not every project earned the migration. Apps with heavy client-side state — drag-and-drop editors, real-time collaboration UIs, anything where most of the screen is interactive — got minimal benefit from server components and a real cost in mental-model retraining. Pages Router also stayed sensible for projects pinned to libraries that had not shipped React Server Components support yet (a moving target, but still real for some auth providers and rich-text editors as of this writing). And honestly: when the team did not have a free quarter to absorb new caching semantics, we would recommend deferring. App Router rewards teams that can think in cache layers; it punishes teams that just want JSX and a deployment URL.
After half a dozen migrations, these are the patterns we keep returning to:
- Move static-content pages first (marketing, docs, blog), defer interactive surfaces until the team's comfort level is high.
- Apply 'use client' at the leaf component, not the layout — every 'use client' at a parent forfeits the server-rendering benefits of the whole subtree.
- Keep pages/api until route handlers are proven for your workload — they coexist cleanly, no need to rewrite working endpoints on day one.
- Test ISR end-to-end after migration. The semantics shifted from getStaticProps + revalidate to the revalidate export plus revalidateTag. Cache misses look different.
- Wire fetch() caching deliberately. Default force-cache caught us once — a third-party rate-limited API got hammered when we forgot to set { cache: 'no-store' }.
- Bring in our web development team for the migration if there is no slack on the engineering side. App Router rewards experience.
Five factors we use when scoping a migration:
SEO and ISR. Pages Router has battle-tested ISR through getStaticProps + revalidate. App Router uses the revalidate export and revalidateTag() for fine-grained invalidation. Our take: equivalent for marketing sites; App Router wins where time-bound data needs targeted revalidation.
Learning curve. Pages Router takes about a day to internalize for an experienced React engineer. App Router takes one to two weeks of real work to internalize server components, the new caching layer, and route handler semantics. Our take: budget the team ramp into the migration estimate or it lands late.
RSC library compatibility. Pages Router is universally compatible. App Router needs every client-state library in the tree to play nicely with React Server Components. Our take: audit your top five libraries before committing — most have shipped RSC support, but the one that has not will hold up the rollout.
Third-party libraries. Pages Router: pick anything. App Router: requires 'use client' boundaries and sometimes wrapper components for libraries that read browser APIs at module scope. Our take: the wrapper layer is small but real; budget a half-day per major library.
Real cost in dev hours. A 40-page marketing site: 2–3 weeks. A SaaS app — think dashboards, auth, third-party libraries, the shape of a job-matching platform or a tax credit portal — runs 6–8 weeks. Our take: these are NerdHeadz numbers from real projects; multiply by 1.5 if your team is also learning App Router during the migration. Pair with the Vercel AI SDK if you are adding streaming AI features at the same time — it slots cleanly into App Router's streaming model.
For more on the larger engagement shape, see our custom software development approach.
It works well for a specific set of problem shapes — and fails predictably on others.
Web + mobile sharing a TypeScript SDK, active engineering team, ongoing iteration. App Router buys you fewer client bundles, server-only secrets, and OTA-fast JS updates via Vercel.
Drag-and-drop editors, real-time collab UIs, anything where most of the screen is interactive. The bridge is the bottleneck; migration cost rarely pays back without a concrete win.
Five pages of static content with occasional updates. Astro or plain MDX in a repo ships faster, cheaper, and with simpler hosting than Next.js.
We move existing Next.js apps from Pages Router to App Router with minimal disruption — page-by-page, library-by-library, ISR semantics tested end-to-end.
Render content on the server, stream slow parts independently, and ship less JavaScript to the browser. Real wins for content-heavy and data-fetching pages.
Time-based and tag-based cache invalidation with revalidatePath and revalidateTag. Fast static pages with surgical updates when content changes.
Next.js route handlers replace pages/api when the workload is proven. We keep both running where it makes sense — no rip-and-replace.
Deploy on Vercel for the default path, Cloudflare for edge-heavy or cost-sensitive workloads. Preview URLs per PR, instant rollbacks, and observability.

Stateful multi-step flow with server-rendered initial state, client-side persistence across sessions, and an admin dashboard for case review. Real ISR + revalidateTag patterns under the hood.

Two-sided marketplace with role-based onboarding, matching engine, and employer + candidate dashboards.
Audit current routing, data-fetching patterns, and third-party library RSC compatibility. Identify the concrete wins App Router unlocks for this product — server components, streaming, OTA-fast iteration.
Convert two high-value pages to App Router as a proof. Benchmark TTFB and bundle size against the Pages Router baseline. Validate the migration cost estimate before committing.
Migrate remaining routes page-by-page. Wire ISR with revalidateTag for surgical invalidation. Add Reanimated for performance-critical animations. Test end-to-end on every cache path.
Architecture documentation, runbook for the migration patterns, walkthrough for the client engineering team. Test coverage on the migrated routes; on-call coverage during the first week post-launch.
Hear it straight from our customers.
This system has been a dream of mine for almost a year. I have tried to build it myself and finally came to the conclusion I needed help. The NerdHeadz team has built me exactly what I was dreaming about and more! Working with them has been an absolute pleasure. I can't thank them enough.
We take on tough challenges and turn them into simple, effective solutions for you.
We build fast, reliable apps that perfectly fit your project requirements.
Our solutions grow and adapt alongside your business, helping you stay ahead.
We maintain open communication and work with you every step of the way.
Depending on what you're actually building, one of these may fit better.
Ask our demo agent about scope, cost, and timelines. Hands you off to a human if you want.
Open the agent →30 minutes with one of our AI engineers. Scoped proposal back within 48 hours.
Pick a time →