Dev Pattern Labs logo
Dev Pattern Labs Blog
Next.js 6 min readOct 1, 2026

Next.js App Router Complete Guide: From Pages to Layouts

A comprehensive guide to the Next.js 15 App Router — covering file-system routing, layouts, server components, streaming, and metadata APIs.

Dev Pattern Labs Author

Dev Pattern Labs

Peer-reviewed technical tutorial · Production tested

Next.js App Router code on a monitor
Executive Summary & Key Insight

A comprehensive guide to the Next.js 15 App Router — covering file-system routing, layouts, server components, streaming, and metadata APIs. This practical guide covers step-by-step setup, real-world code snippets, security hardening, and common production edge cases.

Advertisement

Introduction

The Next.js App Router, introduced in Next.js 13 and stabilised in Next.js 14–15, fundamentally changes how you build React applications. Instead of the legacy pages/ directory, you now work inside the app/ directory where every folder maps to a URL segment — and every file inside those folders has a specific role.

This guide walks you through every key concept of the App Router so you can build production-grade Next.js 15 applications confidently.


Prerequisites

  • Node.js 18.17 or later
  • Familiarity with React and JavaScript/TypeScript
  • A basic understanding of HTTP (GET, POST, etc.)

1. Creating a Next.js 15 App

npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app
npm run dev

The --app flag scaffolds the App Router structure. You'll see an app/ directory instead of pages/.


2. File-System Routing

The App Router maps the folder structure directly to URL segments:

File pathURL
app/page.tsx/
app/about/page.tsx/about
app/blog/[slug]/page.tsx/blog/:slug
app/shop/[...segments]/page.tsx/shop/*

Special files

Each folder can contain these reserved filenames:

  • page.tsx — the route's UI
  • layout.tsx — persistent wrapper (doesn't re-render on navigation)
  • loading.tsx — automatic Suspense boundary
  • error.tsx — error boundary (must be a Client Component)
  • not-found.tsx — rendered when notFound() is called
  • route.ts — API endpoint (no UI)

3. Layouts and Nested Layouts

Layouts are the most powerful concept in the App Router. A layout renders once and persists across child route navigations — meaning your header, sidebar, or shell won't re-mount.

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

You can nest layouts:

app/
  layout.tsx          ← wraps everything
  dashboard/
    layout.tsx        ← wraps only /dashboard routes
    page.tsx          ← /dashboard
    settings/
      page.tsx        ← /dashboard/settings

The dashboard layout can add a sidebar that persists across /dashboard/* without affecting the root layout.


4. Server Components vs Client Components

By default, every component in the app/ directory is a React Server Component (RSC). They:

  • Run only on the server
  • Can access databases, file systems, and environment variables directly
  • Cannot use hooks (useState, useEffect) or browser APIs
  • Produce zero JavaScript sent to the client

To opt into a Client Component, add 'use client' at the top of the file:

'use client';
import { useState } from 'react';

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

The key rule: Client Components can import other Client Components, but they cannot import Server Components. Server Components can import both.

When to use each

Use Server Component whenUse Client Component when
Fetching dataUsing useState or useEffect
Accessing the databaseHandling user events
Reading environment variablesUsing browser APIs
Rendering static contentIntegrating third-party libraries that use hooks

5. Data Fetching in Server Components

Since Server Components run on the server, you can fetch data directly — no useEffect needed:

// app/blog/page.tsx
async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 }, // ISR — revalidate every hour
  });
  return res.json();
}

export default async function BlogPage() {
  const posts = await getPosts();

  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  );
}

Next.js extends the native fetch API with caching options:

  • { cache: 'force-cache' } — cache forever (default in some cases)
  • { cache: 'no-store' } — always fetch fresh data
  • { next: { revalidate: 60 } } — ISR — revalidate after N seconds
  • { next: { tags: ['posts'] } } — cache tag for on-demand revalidation

6. Streaming with Suspense

The App Router supports React's streaming architecture. Wrap slow components in <Suspense> to show a fallback immediately:

import { Suspense } from 'react';
import SlowComponent from './SlowComponent';

export default function Page() {
  return (
    <div>
      <h1>My Page</h1>
      <Suspense fallback={<p>Loading data…</p>}>
        <SlowComponent />
      </Suspense>
    </div>
  );
}

Or use the automatic loading.tsx file — Next.js wraps the page.tsx in Suspense automatically:

// app/dashboard/loading.tsx
export default function Loading() {
  return <div className="skeleton" />;
}

7. Route Groups and Private Folders

Use route groups (groupName) to organise routes without affecting the URL:

app/
  (marketing)/
    page.tsx        ← /
    about/page.tsx  ← /about
  (app)/
    dashboard/
      page.tsx      ← /dashboard

Both groups can share separate layouts without the group name appearing in the URL.

Private folders start with _ and are excluded from routing:

app/
  _components/     ← not a route
  _lib/            ← not a route
  page.tsx         ← /

8. Metadata API

The App Router provides a first-class Metadata API for SEO:

// Static metadata
export const metadata = {
  title: 'My Page',
  description: 'Page description',
};

// Dynamic metadata
export async function generateMetadata({ params }) {
  const post = await getPost(params.slug);
  return {
    title: post.title,
    description: post.description,
    openGraph: {
      images: [post.coverImage],
    },
  };
}

9. Route Handlers (API Routes)

Create API endpoints using route.ts files:

// app/api/posts/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  const posts = await fetchPostsFromDB();
  return NextResponse.json(posts);
}

export async function POST(request: Request) {
  const body = await request.json();
  const newPost = await createPost(body);
  return NextResponse.json(newPost, { status: 201 });
}

10. Parallel and Intercepting Routes

Parallel routes let you render multiple pages in the same layout simultaneously using slots (@slot):

app/
  layout.tsx
  @modal/
    page.tsx
  page.tsx

Intercepting routes let you render a route within the current layout context — perfect for modals that show a photo without losing the feed behind it. Prefix with (.), (..), or (...) depending on how many levels to intercept.


Conclusion

The Next.js App Router is a significant leap forward in how React applications are structured. The key takeaways are:

  1. Layouts persist across navigations — use them for persistent UI
  2. Server Components run on the server — use them for data fetching
  3. Client Components opt into interactivity — use 'use client' when you need hooks
  4. Streaming with Suspense delivers content progressively
  5. Route Handlers replace the old pages/api/ directory

Mastering these concepts gives you the foundation to build any type of Next.js application — from marketing sites to complex dashboards.

To continue leveling up your Next.js architecture, check out our companion guides:

Tags:#Next.js#App Router#React#server components#routing
Dev Pattern Labs Engineering Team

Written by Dev Pattern LabsCore Engineering

Dev Pattern Labs is an engineering lab and digital consultancy specializing in custom Next.js web applications, WooCommerce REST API integrations, and workflow automation for growing businesses.

Advertisement

Recommended Companion Articles

API documentation and code on a monitor
Next.js

Building REST APIs with Next.js Route Handlers

Learn to build production-ready REST APIs with Next.js Route Handlers. Covers GET, POST, PUT, DELETE methods, NextRequest/NextResponse, query params, CORS, streaming responses, and dynamic segments.

11 min read