What Is Next.js and the App Router
The idea in one sentence
Section titled “The idea in one sentence”Next.js is a React framework that owns routing, rendering, data fetching, bundling, and optimization for you — and its current model, the App Router, runs your components on the server by default.
Next.js is a React framework, not just a router
Section titled “Next.js is a React framework, not just a router”Plain React gives you a component model and nothing else — no routing, no server, no build pipeline. Next.js fills that gap. It is the layer that decides how a URL maps to code, where that code runs, and how the result reaches the browser.
Concretely, the framework provides:
- Routing — folders under
app/become URL segments; there is no route config file to maintain. - Rendering — it renders on the server (static or dynamic), streams HTML, and hydrates only what needs interactivity.
- Data fetching — you can
awaitdata directly inside a component, on the server, with no client round-trip. - Bundling — it compiles and splits your code with Turbopack, so each route ships only what it needs.
- Optimizations — images, fonts, scripts, and metadata all have built-in components and APIs.
A route is just a file that default-exports a React component:
export default function HomePage() { return <h1>Hello from a Server Component</h1>;}App Router vs. Pages Router
Section titled “App Router vs. Pages Router”Next.js has two routing systems. The App Router (the app/ directory) is the current, recommended model, built on React Server Components. The Pages Router (the pages/ directory) is the older model; it still works and is fully supported, but it is not where new features land.
The differences are structural, not cosmetic:
app/ pages/ layout.tsx _app.tsx page.tsx index.tsx blog/ blog/ page.tsx index.tsxIn the App Router, components are Server Components by default and data fetching happens inline with async/await. In the Pages Router, every component is a Client Component and data comes from special functions like getServerSideProps. This course is App-Router-first; the Pages Router appears only where migrating an existing app matters.
What create-next-app gives you
Section titled “What create-next-app gives you”You scaffold a new project with one command:
npx create-next-app@latest my-appThe recommended defaults set you up with TypeScript, ESLint, Tailwind CSS, the App Router, and an AGENTS.md file. The generated tree centers on app/:
my-app/ app/ layout.tsx # root layout (required) page.tsx # the "/" route next.config.ts package.json tsconfig.jsonFrom here, npm run dev starts the development server and you are looking at a live App Router app.
The request lifecycle, in one paragraph
Section titled “The request lifecycle, in one paragraph”A request to an App Router route passes through more stages than “run a function, return HTML.” In order: it optionally passes through proxy.ts, Next.js matches it to a route segment, your Server Components render into an RSC payload (with the framework’s cache layers deciding what’s fresh vs. reused), the result streams to the browser as HTML, the browser hydrates the Client Components inside it, and every navigation after that first load fetches more RSC payload instead of a full page. A Server Action call is a POST request that re-enters this same pipeline. Each of those stages is taught in its own lesson elsewhere in this course; The Request Lifecycle walks the whole thing end to end, with the real headers and payloads proved in a running app.
flowchart LR Req[Browser request] --> Router[App Router] Router --> RSC[Server Components render on server] RSC --> HTML[Streamed HTML] Router --> Bundle[Minimal client bundle] HTML --> Page[Interactive page] Bundle --> Page
Mental Model
Section titled “Mental Model”Think of Next.js as everything React deliberately leaves out: it is the layer that decides where your component code runs (server vs. browser), when it runs (build time, request time, or both), and how the result gets to a user. The App Router is not a new templating language bolted onto React — it is Next.js’s current answer to those three questions, built around React Server Components instead of a client-only single-page app.
Trade-offs
Section titled “Trade-offs”| What you get | Benefit | Cost |
|---|---|---|
| App Router (Server Components by default) | Data fetching inline with await, minimal client JS, streaming | New mental model if you learned React as client-only |
| Pages Router (kept for migration) | Familiar getServerSideProps/getStaticProps model, huge existing ecosystem | Every component is a Client Component; no new features land here |
create-next-app recommended defaults | Fastest path to a working, correctly-configured project | Customizing later means understanding what the defaults chose for you |
| Framework owning routing/rendering/bundling | You write far less infrastructure code | You must learn the framework’s conventions, not just React’s API |
Common Misconceptions
Section titled “Common Misconceptions”- “Next.js is just a router for React.” Routing is one of five things it owns — it also decides rendering strategy, data fetching ergonomics, bundling, and built-in optimizations for images/fonts/scripts/metadata.
- “The App Router and Pages Router are two ways to write the same thing.” They are structurally different: App Router components are Server Components by default with inline
async/awaitdata fetching; Pages Router components are all Client Components fed by separate functions likegetServerSideProps. Code does not port over 1:1. - “Every request just runs my page function and returns HTML.” A request passes through proxy, route matching, RSC rendering against multiple cache layers, streaming, and (on later navigations) a client-side RSC fetch — see The Request Lifecycle for the full picture.
Reading AI-generated code
Section titled “Reading AI-generated code”When a generated snippet claims to be “a Next.js page,” check for these before trusting it:
- Does it live under
app/and default-export a component — or does it use Pages-Router-only APIs (getServerSideProps,getStaticProps, apages/file) inside what’s supposed to be an App Router project? - Does it assume the component is a Client Component (using
useState/useEffectwith no"use client") when it’s actually a Server Component by default? - Does it fetch data through a separate API call from the component, when an
asyncServer Component couldawaitit directly? - Is it training-data-era advice that predates the App Router — e.g. treating
pages/apias the only way to build an endpoint, when Route Handlers (app/**/route.ts) are the App Router equivalent?
🐛 Spot the bug
export async function getServerSideProps() {const res = await fetch('https://api.example.com/stats')return { props: { stats: await res.json() } }}
export default function Dashboard({ stats }: { stats: { views: number } }) {return <p>Views: {stats.views}</p>}Show the answer
getServerSideProps is a Pages Router export — it does nothing inside app/. In the App Router, Dashboard is already a Server Component by default, so it can await the fetch directly in its own body instead of exporting a separate data-loading function; stats would be undefined here because Next.js never calls getServerSideProps for App Router routes. The fix is to make Dashboard itself async and await fetch(...) inline, the pattern covered in Server and Client Components.