All Posts
Code22 March 20264 min read

Next.js App Router: Patterns I Actually Use

After shipping several production apps with the App Router, here are the layout, data-fetching, and component patterns that stuck — not the ones from the docs, but the ones that actually scale.

Akbar Malik

The App Router shipped with a lot of promise — and a lot of confusion. After using it in production, I've settled into patterns that actually make sense. Here's what I keep reaching for.

1. Route Groups for Layout Isolation

Route groups (folder) are one of the most underused features. I use them to apply different root layouts without affecting the URL.

app/
  (marketing)/
    layout.tsx   ← no header/sidebar
    page.tsx
  (dashboard)/
    layout.tsx   ← full app shell
    settings/
    analytics/

This keeps your marketing pages completely isolated from your app shell — no conditional rendering, no prop drilling the layout variant down.


2. Server Components as Data Boundaries

Stop fetching data in Client Components unless you need interactivity. Let Server Components own the data layer.

// app/dashboard/page.tsx — Server Component
export default async function DashboardPage() {
  const user = await getUser()          // Direct DB/API call
  const stats = await getStats(user.id)

  return <StatsGrid stats={stats} user={user} />
}

StatsGrid can be a Client Component for animations, but the data never touches the client bundle. This keeps your API keys server-side and your bundle lean.


3. Parallel Routes for Modals

Instead of managing modal state in context, use @modal slots. The URL reflects the modal state, the back button closes it, and it all works without any global state.

nextjsapp-routertypescriptreact