- Next.js
- Pages Router & Migration Strategy
- Incremental Dual-Router Coexistence in Production
Incremental Dual-Router Coexistence in Production
Next.js supports incremental migration by allowing the Pages Router (pages/) and App Router (app/) directories to coexist in the same project. Routes migrate page-by-page. While App Router takes priority over Pages Router for route resolution, defining the identical URL in both routers is an error. Navigating between routers triggers a hard page transition rather than an SPA soft navigation.
Learning Objectives
Design an incremental, low-risk migration strategy for multi-million-line codebases.
Understand route resolution priority between app/ and pages/.
Explain why cross-router navigations trigger hard browser reloads.
Share state and session cookies smoothly between Pages and App Router segments.
Prerequisites & Background Knowledge
Why Interviewers Care
Large enterprises (Target, TikTok, Hulu) cannot rewrite entire codebases overnight. Interviewers assess your ability to execute zero-downtime incremental migrations.
The Challenge
How does Next.js handle dual-router coexistence? Outline an enterprise migration plan to migrate routes incrementally without downtime, and explain what happens during cross-router navigation.
Code Architecture & Implementation
1my-enterprise-app/2├── pages/ # Legacy Pages Router (unmigrated routes)3│ ├── _app.tsx4│ ├── _document.tsx5│ ├── checkout.tsx # Still on Pages Router (sensitive checkout)6│ └── account/7│ └── settings.tsx # Still on Pages Router8│9├── app/ # Modern App Router (migrated routes)10│ ├── layout.tsx # App Router Root Layout11│ ├── page.tsx # Marketing Homepage (Migrated!)12│ └── blog/13│ ├── page.tsx # Blog Index (Migrated!)14│ └── [slug]/15│ └── page.tsx # Blog Detail (Migrated!)16│17└── package.json
Architectural Explanation
Next.js is specifically architected to allow both routers to run side-by-side. The routing engine checks the incoming request: if a matching route exists in app/, it serves the App Router component; otherwise, it checks pages/. Because the two routers use different client-side routing runtimes (next/navigation vs next/router), navigating across router boundaries falls back to a standard browser hard navigation. By sharing session cookies and authentication tokens, user login state persists seamlessly across both environments.
Common Mistakes & Anti-Patterns
Attempting a high-risk "big bang" rewrite of the entire codebase at once, leading to delayed releases and regressions.
Leaving duplicate routes in both `app/` and `pages/`, causing build conflicts.
Expecting React Context created in `_app.tsx` to be accessible inside `app/` routes (they have completely separate React component trees).
Interview Follow-Up Traps
The interviewer asks: "Can a layout in app/ wrap a page in pages/?" No! The component trees are completely separate. Pages in `pages/` are wrapped by `_app.tsx`; pages in `app/` are wrapped by `app/layout.tsx`.
Frequently Asked Questions
Can you use Server Actions from Pages Router pages?
No. Server Actions are exclusively supported in the App Router.
Does Next.js build take longer with dual routers?
Build times may increase slightly because both compilers and route manifests are evaluated.
