- Next.js
- Pages Router & Migration Strategy
Pages Router & Migration Strategy
A majority of enterprise companies have existing production codebases built on the Pages Router that require incremental migration.Master legacy data fetching APIs (getServerSideProps, getStaticProps, getStaticPaths) and understand their exact equivalents in App Router.Formulate zero-downtime dual-router coexistence strategies, migrate navigation hooks safely, and refactor monolithic _app.js and _document.js files into modern layouts.
Pages Router Data Fetching: getServerSideProps vs getStaticProps
In Pages Router, data fetching was defined per-page via exported functions: getServerSideProps executed on every request on the server (SSR), while getStaticProps executed at build time to produce static HTML/JSON (SSG), with optional revalidate for ISR. Unlike App Router, data fetching could not be colocated inside child components.
Custom _app.js and _document.js Lifecycle
In Pages Router, _document.js rendered strictly on the server to customize the initial HTML shell (<html>, <head>, <body>), but could not contain client logic. _app.js initialized every page on both server and client, serving as the central hub for global CSS, layout persistence, and global providers. In App Router, both are replaced by app/layout.tsx.
Mapping Pages Router APIs to App Router Equivalents
Migrating from Pages Router to App Router involves direct API mapping: getServerSideProps maps to async Server Components; getStaticProps maps to async fetch or "use cache"; getStaticPaths maps to generateStaticParams; next/head maps to generateMetadata; and API routes (pages/api) map to Route Handlers (route.ts).
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.
Migrating Navigation: next/router vs next/navigation
In Pages Router, next/router provided a monolithic useRouter() hook returning pathname, query, asPath, and router events. In App Router, next/navigation decomposes these responsibilities into specialized hooks: useRouter() for programmatic navigation, usePathname() for the current URL path, useSearchParams() for query parameters, and useParams() for dynamic route segments.
