vercel/next.js
Pages Router
The original Next.js router, rooted at the pages/ directory in user code. Still fully supported alongside the App Router. Many production apps run both routers in the same project.
Anatomy
graph TD
Request[Request] --> Match[base-server matches /pages route]
Match --> Module[Pages route module<br/>route-modules/pages/]
Module --> Render[render.tsx<br/>renderToHTML]
Render --> GetData[getServerSideProps<br/>getStaticProps<br/>getInitialProps]
GetData --> ReactRender[React.renderToString /<br/>renderToPipeableStream]
ReactRender --> Response[HTML response]Server side
render.tsx
packages/next/src/server/render.tsx (51 KB) is the entry point. It:
- Loads the page module, the
_app, and the_documentfrom.next/. - Runs the page's data-fetching method (
getServerSideProps,getStaticProps,getInitialProps). - Calls React's
renderToString(or the streaming variant) on<App pageProps={...}><Component /></App>. - Wraps the result in the
<Document>shell. - Serializes data into the
__NEXT_DATA__script tag for client hydration.
Despite being part of the older router, this file is still actively maintained — App Router improvements often have a Pages Router counterpart.
Static and SSG
getStaticProps returns either pre-rendered HTML files (built via packages/next/src/build/static-paths/) or pages with a configured revalidate interval. The runtime serves the cached HTML and re-runs the data fetch on revalidation triggers.
API routes
pages/api/* files become serverless API endpoints. They are dispatched through packages/next/src/server/route-modules/pages-api/ and run in the Node runtime.
The request and response objects are augmented with helpers like req.cookies, res.json(), res.status(). The augmentation lives in packages/next/src/server/api-utils/.
Built-in pages
packages/next/src/pages/ contains the framework's built-in _app, _document, and _error defaults that are used when the user doesn't provide their own.
Client side
router.ts
packages/next/src/client/router.ts is the user-facing API surface (useRouter, withRouter). It re-exports the router state from packages/next/src/shared/lib/router/router.ts (2,630 lines) — the actual Pages Router state machine.
The state machine handles:
- Client-side navigation (
router.push,router.replace) - Prefetching of
next/linktargets - Scroll restoration
- Page transitions
- Locale-aware routing for i18n
- Re-renders when
getServerSidePropsdata changes
Hydration
After the server renders the HTML, the client picks up the __NEXT_DATA__ JSON, hydrates <App> with it, and starts the router. The hydration entry is packages/next/src/client/index.tsx (31 KB).
Coexistence with the App Router
Both routers can serve the same project:
- A request to
/aboutmatches a Pages Router page ifpages/about.tsxexists. - A request to
/dashboardmatches an App Router page ifapp/dashboard/page.tsxexists. - If both define the same path, the App Router wins by default. The framework warns about the conflict at build time (see
packages/next/src/build/validate-app-paths.ts).
The route matcher managers (packages/next/src/server/route-matcher-managers/) coordinate this dispatch.
Data fetching APIs
| API | When | File |
|---|---|---|
getInitialProps |
Pre-Next.js-9 legacy | Page-level |
getServerSideProps |
SSR per request | Page-level |
getStaticProps |
Build-time / ISR | Page-level |
getStaticPaths |
Defines dynamic SSG paths | Page-level |
The framework reads these exports via SWC analysis (packages/next/src/build/analysis/) at build time to decide each page's rendering mode.
Custom Document and App
Users override the document shell and the per-page wrapper:
pages/_document.tsx— defines<html>,<body>, and where<Head>,<Main>, and<NextScript>mount.pages/_app.tsx— wraps every page; common place for layout and providers.
Default implementations live in packages/next/src/pages/_document.tsx and _app.tsx.
i18n
The Pages Router has built-in support for locale subpaths and domain locales. Configuration is the i18n block in next.config.js. Implementation: packages/next/src/server/lib/i18n-provider.ts. The App Router handles internationalization via user-defined middleware and dynamic segments — there is no built-in i18n config for the App Router.
Integration points
- The build pipeline analyzes page exports to decide rendering mode (see build).
next/linkandnext/routerfrom this codebase back the public API.- Pre-rendered output is cached by the caching layer.
pages/api/*requests are dispatched by the same server runtime as other routes.
Entry points for modification
- To change Pages rendering:
packages/next/src/server/render.tsx. - To add a new data-fetching helper:
packages/next/src/build/analysis/(recognition) +packages/next/src/server/route-modules/pages/(execution). - To change client navigation:
packages/next/src/shared/lib/router/router.ts. - To change i18n behavior:
packages/next/src/server/lib/i18n-provider.ts.
Key source files
| File | Purpose |
|---|---|
packages/next/src/server/render.tsx |
Pages Router server renderer |
packages/next/src/server/route-modules/pages/ |
Pages route module |
packages/next/src/server/route-modules/pages-api/ |
API route module |
packages/next/src/server/api-utils/ |
req/res augmentation |
packages/next/src/pages/ |
Built-in _app, _document, _error |
packages/next/src/client/router.ts |
useRouter, withRouter user-facing API |
packages/next/src/shared/lib/router/router.ts |
Client router state machine |
packages/next/src/client/index.tsx |
Pages Router hydration entry |
packages/next/src/server/lib/i18n-provider.ts |
i18n locale resolution |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.