App Router Basics — How It Differs from Pages Router
App Router Basics — How It Differs from Pages Router
💡 Why Learn This? — The Pages Router Era Is Winding Down
4 Core Concepts of App Router — Folders Are Routes
1. File-Based Routing (Folders as URLs)
The folder structure under src/app/ maps directly to URLs.
- ▸Only
page.tsxbecomes a route (files with other names do not). - ▸
[name]folders are dynamic segments — they come in as parameters.
2. Server Components Are the Default
Components inside App Router are Server Components by default unless explicitly marked otherwise.
- ▸Only the fully rendered HTML is sent to the browser → 0KB of client-side JS bundle.
- ▸Functions can be
async. You can useawaitdirectly inside a component. - ▸Accessing DBs, the filesystem, and environment variables is fine (none of it leaks to the browser).
3. Client Components Are Explicitly Opted In
When browser features like useState, onClick, or useEffect are needed, add 'use client' at the top of the file:
- ▸Only this component is sent to the client — the parent Server Component stays on the server.
- ▸The Server ↔ Client boundary becomes explicit → bundle size stays under control.
4. layout.tsx — Shared UI per Folder
- ▸No
_app.tsxor_document.tsx. - ▸Each nested route naturally inherits the
layout.tsxin its own folder. - ▸
loading.tsx,error.tsx, andnot-found.tsxin the same folder are also applied automatically.
💡 💡 5 Common Gotchas When Moving from Pages to App
1. 'use client' Goes Only Where Needed — It Does Not Spread Upward
Even if a Server Component imports a Client Component, the parent remains a Server Component. The reverse is not allowed (Client → Server imports are not permitted).
2. async Components Are Only Possible in Server Components
Client Components cannot be async functions — they conflict with useState and useEffect. Keep data fetching on the server side and pass the results down as props.
3. fetch Is Automatically Cached and Deduplicated
Next.js deduplicates fetch calls to the same URL within the same render. You can disable this with cache: 'no-store' or set an ISR interval with next: { revalidate: 60 }.
4. Client-Only Hooks Must Stay in Client ComponentsuseState, useEffect, useContext, usePathname, and useSearchParams are all client-only. Using them in a Server Component will cause a build error.
5. Environment Variables: the NEXT_PUBLIC_ Prefix Rule Still Applies
Server Components can access all env vars. Client Components can only see those prefixed with NEXT_PUBLIC_ — the same rule as in Pages Router.