Back to roadmaps nextjs Course

App Router Routing Basics

Next.js uses a file-system based router. The folder structure inside the app directory directly determines your application routes.


1. Directory and Route Mapping

In the App Router, routes are defined by directories. A route becomes publicly accessible only when you add a page.tsx file inside that directory:

src/app/
├── page.tsx          # Homepage (/)
├── about/
│   └── page.tsx      # About page (/about)
└── blog/
    ├── page.tsx      # Blog index page (/blog)
    └── first-post/
        └── page.tsx  # Nested post page (/blog/first-post)

If a folder does not contain a page.tsx file, it acts purely as a organization folder and will return a 404 error if visited.


2. Layouts and Pages

Two file conventions form the core of Next.js routing:

  • page.tsx: Renders the unique UI of a route.
  • layout.tsx: Renders shared UI that wraps the current route and all sub-routes nested below it.

Here is how page and layout coordinate:

// src/app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex">
      <aside className="w-64 bg-gray-100 p-4">Dashboard Sidebar</aside>
      <main className="flex-1 p-8">{children}</main>
    </div>
  );
}
// src/app/dashboard/page.tsx
export default function DashboardPage() {
  return <h1>Welcome to your Dashboard overview!</h1>;
}

When visiting /dashboard, the page content renders directly inside the layout children parameter placeholder.


3. Nesting Layouts

Layouts nest automatically. The layout declared in /app/layout.tsx serves as the root layout wrapper for the entire site.

If you add a layout in /app/dashboard/layout.tsx, it will wrap the dashboard sub-pages, but will itself render inside the outer root layout. This enables complex nested dashboards with persistent navigation frames.


4. Link-Based Navigation

To navigate between pages, never use standard anchor tags (like a href). Standard anchor tags trigger a full page refresh, discarding React state. Always use the Next.js Link component for client-side navigation:

import Link from "next/link";

export default function Navbar() {
  return (
    <nav className="flex gap-4">
      <Link href="/">Home</Link>
      <Link href="/about">About Us</Link>
    </nav>
  );
}
Published on Last updated: