What Is the App Router?
The App Router has been the standard way of building Next.js applications for years now. What was a novelty back in the Next.js 13 days is today a mature, production-proven model - built on React Server Components, with the lightning-fast Turbopack as the default bundler. In this article you'll learn:
- What Server Components are and why they're the default
- How folder-based routing works
- When to reach for Client Components
App Router Basics
The App Router uses the app/ folder structure - each folder represents a URL segment, and a page.tsx file defines the page:
// app/blog/page.tsx
export default function BlogPage() {
return <h1>Blog</h1>
}
The older pages/ directory is still supported for existing projects, but new applications are built in app/ - and that's where the framework's development is focused.
Server Components vs Client Components
Server Components (default):
- Rendered on the server
- Zero JavaScript sent to the browser
- Direct access to databases and secrets
- Better SEO and faster loading
After years in production, Server Components are a mature, well-documented model - the entire ecosystem (UI libraries, CMSs, ORMs) works with them out of the box.
Client Components ('use client'):
- Interactivity (useState, useEffect)
- Event handlers
- Browser APIs
The rule is simple: server by default, client only where you need interactivity.
Practical Example
Let's fetch data directly in a server component - no useEffect, no extra libraries:
// app/posts/page.tsx
async function getPosts() {
const res = await fetch('https://api.example.com/posts')
return res.json()
}
export default async function PostsPage() {
const posts = await getPosts()
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
)
}
The component is asynchronous, data is fetched on the server, and the browser receives ready-made HTML.
Routing and Navigation
Navigation between pages happens through the Link component, with automatic prefetching in the background:
import Link from 'next/link'
export default function Navigation() {
return (
<nav>
<Link href="/blog">Blog</Link>
<Link href="/about">About</Link>
</nav>
)
}
Loading States and Error Handling
The App Router has built-in conventions for loading and error states - just add the right file:
// app/blog/loading.tsx
export default function Loading() {
return <div>Loading...</div>
}
// app/blog/error.tsx
'use client'
export default function Error({ error, reset }) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
)
}
The loading.tsx file automatically wraps the page in a Suspense boundary, and error.tsx acts as an error boundary for the whole segment.
Turbopack - Fast Development with Zero Config
Next.js now ships with the stable Turbopack as its default bundler - the Rust-based successor to Webpack. In practice that means near-instant dev server startup and blazing-fast hot reload even in large projects. There is nothing to configure - it just works.
Summary
The App Router is the obvious choice for any new Next.js application today. With Server Components you build faster, more SEO-friendly sites while shipping less client-side code.
Key takeaways:
- Server Components are the default - and should stay that way
- Client Components only where interactivity is needed
- The
app/folder structure is intuitive and scales well - Loading and error states are built-in conventions, not boilerplate
- Turbopack delivers fast development with zero configuration
Next Steps
Want to learn more about Next.js? Check out our other articles or contact us - we'll help you build a modern application!