Navigating the New App Router in Next.js 14+
In this module, you’ll master one of the most powerful features of Next.js 14 — the new App Router. Say goodbye to pages/
and embrace the future of routing in React with full flexibility, layouts, templates, and more — all organized under the src/app/
directory with TypeScript.
📁 File-Based Routing in src/app/
Next.js 14 uses the App Router system based on your file structure. Inside src/app/
, each folder becomes a route.
Example structure:
src/
└── app/
├── page.tsx → Renders `/`
└── about/
└── page.tsx → Renders `/about`
Each folder must contain a page.tsx
file to be a route. You can also include special files like layout.tsx
, loading.tsx
, and error.tsx
.
🔁 Shared Layouts & Nested Routes
With App Router, you can nest routes and layouts easily.
✅ Example:
src/
└── app/
├── layout.tsx → Global layout (wraps entire app)
├── page.tsx → Home
└── dashboard/
├── layout.tsx → Dashboard-specific layout
├── page.tsx → /dashboard
└── settings/
└── page.tsx → /dashboard/settings
Each nested layout.tsx
wraps only the routes below it.
// src/app/dashboard/layout.tsx
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="dashboard-wrapper">
<Sidebar />
<main>{children}</main>
</div>
);
}
This makes it easy to implement persistent sidebars, headers, or auth guards.
🔄 Dynamic Routes and Catch-All Routes
Just like in older Next.js versions, you can create dynamic segments:
Dynamic Routes:
src/app/blog/[slug]/page.tsx → /blog/my-first-post
// [slug]/page.tsx
type Props = {
params: { slug: string };
};
export default function BlogPost({ params }: Props) {
return <h1>Blog: {params.slug}</h1>;
}
Catch-All Routes:
src/app/docs/[[...slug]]/page.tsx → /docs, /docs/guide, /docs/guide/setup
Use [[...slug]]
when the path can be optional or deep.
🧩 Special Files: not-found.tsx
, loading.tsx
, and template.tsx
Next.js 14 introduces UI-based routing utilities with these files:
🔴 not-found.tsx
Automatically shown when a route doesn’t exist.
export default function NotFound() {
return <p>Oops! Page not found.</p>;
}
Use notFound()
inside a component to trigger this.
🕓 loading.tsx
Displayed while the page or layout is loading.
export default function Loading() {
return <p>Loading...</p>;
}
Put this inside any folder like /dashboard/loading.tsx
.
📑 template.tsx
Useful when you want a layout to re-initialize state on every navigation. Think of it as a “layout that resets”.
🔗 Navigation with <Link>
, useRouter
, and usePathname
✅ Use <Link>
to Navigate Between Pages
import Link from 'next/link';
<Link href="/about">About</Link>
🧭 useRouter()
For programmatic navigation:
"use client";
import { useRouter } from 'next/navigation';
const router = useRouter();
router.push('/dashboard');
Note:
useRouter
is a Client Component hook, so wrap it inside"use client"
.
📍 usePathname()
To read the current route path:
"use client";
import { usePathname } from 'next/navigation';
const pathname = usePathname(); // returns "/about"
Helpful for conditionally styling nav links or breadcrumbs.
🧠 Pro Tip: Co-locate Your Components
Keep reusable navigation components inside src/components/
:
src/
├── components/
│ └── Navbar.tsx
Then use it inside your layout.tsx
or page components:
import Navbar from '@/components/Navbar';
✅ Summary
By the end of Module 2, you’ve learned:
- How App Router enables powerful file-based routing
- How to use layouts, nested routes, and dynamic paths
- Special files like
loading.tsx
,not-found.tsx
, andtemplate.tsx
- How to navigate using
<Link>
,useRouter()
, andusePathname()
You’re now fully equipped to build scalable and dynamic page structures.
🔜 Coming Up Next:
In Module 3, we’ll design a beautiful UI using Tailwind CSS, explore responsive layouts, and implement dark mode.
Would you like this in blog markdown or HTML format too?