← Back to all posts

Next.js App Router: What Actually Changed and Why It Matters

Breaking down server components, layouts, and data fetching in the new App Router — with real examples you can use today.

The Big Shift

The App Router introduced in Next.js 13 is not just a new folder — it's a fundamentally different mental model. Everything in /app is a React Server Component by default.

Server vs Client Components

// Server Component (default) — runs on server
async function BlogPosts() {
  const posts = await fetch('https://api.example.com/posts').then(r => r.json())
  return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
}

// Client Component — add 'use client' directive
'use client'
import { useState } from 'react'

function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}

Layouts That Actually Work

Shared layouts no longer re-render on navigation. The layout.tsx file wraps all pages in its directory and persists across route changes.

// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Header />
        <main>{children}</main>
        <Footer />
      </body>
    </html>
  )
}
💡

Rule of thumb: start with Server Components. Only add 'use client' when you need interactivity, browser APIs, or React hooks.