Back to Next.js tutorials
Basic12 min read

App Router Basics

The file-system routing model where folders define routes and special files define UI for each segment.

How The App Router Works

The App Router maps folders in the `app` directory to URL segments. A folder named `dashboard` creates the `/dashboard` route. The `page.tsx` file exports the UI for that segment; without it, the folder is a route group organizer but not a publicly accessible URL.

Special files — `layout.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`, `route.ts` — attach behavior to segments. This convention replaces Pages Router files like `_app.tsx` and `getServerSideProps` with colocated route modules.

  • Folders map to URL segments
  • page.tsx required for public routes
  • Special files attach segment behavior
app/
  layout.tsx      // root layout
  page.tsx        // /
  blog/
    page.tsx      // /blog
    [slug]/
      page.tsx    // /blog/:slug

Root Layout First

The root `app/layout.tsx` wraps every page. It must include `<html>` and `<body>` tags. Define global fonts, metadata defaults, providers, and shared chrome here.

Nested layouts add UI per section without remounting parent layout on navigation — navigating between `/dashboard/settings` and `/dashboard/analytics` keeps the dashboard layout mounted while swapping page content.

  • Root layout includes html and body
  • Nested layouts persist across child navigation
  • Global providers belong in root layout

Route Groups and Private Folders

Parentheses folders like `(marketing)` organize routes without affecting the URL — `app/(marketing)/about/page.tsx` serves `/about`. Use groups to split layouts (marketing vs app shell) without nested URL paths.

Prefix folders with underscore (e.g., `_components`) or use colocation patterns to keep non-route files near routes. Only `page.tsx` and route handlers create public endpoints.

  • (group) folders omit URL segment
  • Split layouts without URL nesting
  • Underscore prefixes for non-route folders

Server vs Client Default

Components in the App Router are Server Components by default — no JavaScript shipped for their logic unless they import client modules. Add `"use client"` only where interactivity, hooks, or browser APIs are required.

This default reduces client bundle size dramatically compared to Pages Router where pages were typically client-heavy. Plan client boundaries during route design, not as an afterthought.

  • Server Components are the default
  • "use client" only when needed
  • Design client boundaries early

Migrating Mental Models

Replace `pages/index.tsx` with `app/page.tsx`. Replace `pages/api/*` with `app/**/route.ts` Route Handlers. Replace `getServerSideProps` with async Server Components that fetch directly.

Incremental adoption uses Next.js hybrid mode — both `pages` and `app` directories coexist during migration. New features should land in `app` exclusively.

  • pages/ and app/ can coexist
  • getServerSideProps → async Server Components
  • New features in app/ directory

Get In Touch


Ready to discuss your next project? Drop me a message.