What is the App Router?
The App Router, introduced in Next.js 13 and matured in v15, automatically creates URLs based on the folder/file structure. Every page.tsx file you add inside the app/ folder becomes a page.
Core Routing Logic
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ ├── page.tsx → /blog
│ └── [slug]/
│ └── page.tsx → /blog/any-post-slug
└── contact/
└── page.tsx → /contact
Creating Your First Page
// app/about/page.tsx
export default function About() {
return (
<div className="max-w-2xl mx-auto p-8">
<h1 className="text-3xl font-bold mb-4">About Us</h1>
<p className="text-gray-600">
This page is accessible at /about.
</p>
</div>
);
}
Dynamic Routes
Square brackets [slug] create dynamic segments:
// app/blog/[slug]/page.tsx
interface Props {
params: Promise<{ slug: string }>;
}
export default async function BlogPost({ params }: Props) {
const { slug } = await params; // In Next.js 15, params is now a Promise
return (
<article>
<h1>Post: {slug}</h1>
<p>URL: /blog/{slug}</p>
</article>
);
}
⚠️ Next.js 15 Breaking Change:
params and searchParams are now Promises. Always use await params!
Nested Routes
app/
└── dashboard/
├── layout.tsx ← Layout scoped to /dashboard/*
├── page.tsx → /dashboard
├── settings/
│ └── page.tsx → /dashboard/settings
└── profile/
└── page.tsx → /dashboard/profile
Shared Layouts with layout.tsx
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex">
<aside className="w-64 bg-gray-900 text-white p-4">
<nav>
<a href="/dashboard">Home</a>
<a href="/dashboard/settings">Settings</a>
</nav>
</aside>
<main className="flex-1 p-8">{children}</main>
</div>
);
}
Special Files
| File | Purpose |
|---|---|
| page.tsx | Page content (required) |
| layout.tsx | Shared template (not re-rendered on navigation) |
| loading.tsx | Loading UI (Suspense boundary) |
| error.tsx | Error boundary (must be Client Component) |
| not-found.tsx | 404 page |
| template.tsx | Like layout but re-renders on each navigation |
Önemli Noktalar
- Every page.tsx in app/ creates a URL automatically
- Dynamic routes use [slug] syntax
- In Next.js 15, params is a Promise — always await it
- layout.tsx creates a shared shell for nested pages