βοΈ
EPISODE 07
file-based routing Β· layouts Β· loading Β· error Β· dynamic routes
Next.js App Router
Master Next.js App Router: folders become routes, layouts wrap pages, dynamic segments handle slugs, and special files give you loading and error UI for free.
Next.jsApp Routerlayoutsloadingerror
Duration
β± About 2.5 hours
Level
π Intermediate+
Prerequisite
π― Lesson 5 + React 1β6
OUTCOME
A multi-page Next.js app with nested layouts, dynamic routes, and loading/error UI
What you'll learn
- 1Map folders to routes (page.tsx, layout.tsx)
- 2Nest layouts to share UI
- 3Use dynamic segments ([slug]) and generateStaticParams
- 4Add loading.tsx and error.tsx for built-in states
1. Folder Routing
text
app/
βββ layout.tsx # wraps everything
βββ page.tsx # /
βββ about/
β βββ page.tsx # /about
βββ blog/
β βββ page.tsx # /blog
β βββ layout.tsx # wraps /blog and nested
β βββ [slug]/
β βββ page.tsx # /blog/:slug2. Layouts
tsx
// app/layout.tsx (root)
import "./globals.css";
import Link from "next/link";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<nav><Link href="/">Home</Link> Β· <Link href="/about">About</Link></nav>
<main>{children}</main>
</body>
</html>
);
}Nested layouts inherit from the parent β you can have section-specific headers, sidebars, etc.
3. Dynamic Routes & Static Params
tsx
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map(p => ({ slug: p.slug }));
}
export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return <article><h1>{post.title}</h1>{post.body}</article>;
}4. Special Files: loading & error
tsx
// app/blog/loading.tsx
export default function Loading() { return <p>Loading posts...</p>; }
// app/blog/error.tsx (must be a client component)
"use client";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<p>Something went wrong: {error.message}</p>
<button onClick={reset}>Try again</button>
</div>
);
}Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub β