Guide · Next.js · App Router
Next.js 14 App Router: Complete Guide for Beginners
Everything you need to know about the Next.js App Router — layouts, loading states, error boundaries, server components, and data fetching patterns explained clearly.
Jatinder Sandhu
When Next.js 13 shipped the App Router, it changed how developers think about building React applications. Routing, data fetching, layouts, and loading states all moved into a single, folder-based system built on React Server Components. By Next.js 14, the App Router became the recommended default for every new project.
If you are still on the older Pages Router, or you are new to Next.js entirely, the App Router can feel unfamiliar at first — new file conventions, a new mental model for client vs. server code, and new patterns for fetching data. This guide walks through everything you need to know, in the order you will actually use it on a real project.
I build production Next.js applications for clients regularly, and the App Router is what I reach for on every new build today. This guide is the explanation I wish I had when I started.
File-Based Routing in the App Router
Every route in the App Router lives inside the src/app directory. A folder becomes a URL segment, and a special page.tsx file inside that folder makes the route publicly accessible.
Dynamic segments use square brackets — [slug] — and the value is available to your page as a prop. This is exactly how a page like this blog post is generated.
Layouts: Shared UI That Persists
A layout.tsx file wraps every page inside its folder and any nested folders. Layouts do not re-render when you navigate between pages that share them, which makes them ideal for navigation bars, sidebars, and anything that should stay mounted — like an open modal or a persisted scroll position.
You can nest layouts as deep as you need. The root app/layout.tsx is required in every project — it defines your <html> and <body> tags and is the right place for global fonts, providers, and analytics scripts.
Loading States with loading.tsx
Drop a loading.tsx file next to any page.tsx and Next.js automatically wraps that route in a React Suspense boundary. While the page is fetching its data on the server, your loading UI shows instantly — no manual state management required.
Why it matters
Users see instant feedback on navigation instead of a blank white screen while the server fetches data.
Scope
A loading.tsx file only affects the segment it sits in and everything nested below it.
Error Boundaries with error.tsx
An error.tsx file catches runtime errors inside its route segment and renders a fallback UI instead of crashing the whole app. It must be a Client Component because it uses React state to reset the boundary.
For errors thrown in the root layout itself, use a special global-error.tsx file, since the regular error boundary cannot catch failures above it in the tree.
Server Components vs. Client Components
Every component in the App Router is a Server Component by default. Server Components render on the server, send zero JavaScript to the browser, and can talk to a database or read a file system directly. Add 'use client' at the top of a file only when you need interactivity — state, effects, event handlers, or browser-only APIs.
| Capability | Server Component | Client Component |
|---|---|---|
| Fetch data directly (DB, filesystem) | Yes | No |
| useState / useEffect | No | Yes |
| Ships JavaScript to browser | No | Yes |
| onClick, onChange handlers | No | Yes |
A good rule of thumb: keep as much of your tree as Server Components as possible, and push 'use client' as far down the component tree as you can — often onto a single button or form, not an entire page.
Data Fetching Patterns
Because Server Components run on the server, you can fetch data with a plain async function — no useEffect, no client-side loading spinner logic.
The fetch caching options control your rendering strategy:
- Default (cache: 'force-cache'): static rendering — fetched once at build time.
- cache: 'no-store': dynamic rendering — fetched fresh on every request.
- next: { revalidate: N }: Incremental Static Regeneration — cached, then revalidated every N seconds.
For mutations — form submissions, creating a record, sending a message — use Server Actions instead of building a separate API route. A Server Action is an async function marked with 'use server' that you can call directly from a form or a Client Component.
Common Mistakes Beginners Make
This throws away all the server-rendering benefits. Keep the client boundary as small as possible.
This causes a client-side waterfall. Fetch in a Server Component instead and pass data down as props.
Developers build manual spinners with useState when a single file would handle it automatically.
getServerSideProps and getStaticProps do not exist in the App Router — use async Server Components instead.
Frequently Asked Questions
Is the App Router replacing the Pages Router?
Yes. The App Router is the recommended approach for all new Next.js projects starting with Next.js 13+, and it is the default in Next.js 14 and 15.
Do I need to rewrite my whole app to migrate?
No. Next.js supports incremental adoption — you can run the app/ and pages/ directories side by side and migrate route by route.
Can Server Components use hooks like useState?
No. Hooks only work in Client Components marked with the ‘use client’ directive at the top of the file.
How is this different from getServerSideProps?
Server Components replace that pattern entirely — you just write an async function and await your data directly in the component.
Conclusion
The App Router is not just a new set of file conventions — it is a genuinely different way to build React apps, with Server Components at the center. Once the folder structure, layouts, loading states, and Server/Client boundary click, most developers find it faster to build with than the old Pages Router.
Start small: convert one route, get comfortable with async Server Components, then move on to Server Actions for your forms. I use this exact stack — Next.js App Router, Server Components, and Server Actions — on every client project I build today, and it consistently produces faster, more maintainable applications.
Need help migrating your app to the App Router, or want a Next.js project built the right way from day one? Get in touchand let's talk about your project.