Next.js 15 From Scratch

Ders 3/8 30 dakika

App Router: Pages and File-Based Routing

How does the Next.js App Router work with file-system-based routing? Build powerful navigation with dynamic routes and nested layouts.

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

FilePurpose
page.tsxPage content (required)
layout.tsxShared template (not re-rendered on navigation)
loading.tsxLoading UI (Suspense boundary)
error.tsxError boundary (must be Client Component)
not-found.tsx404 page
template.tsxLike 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