Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Next.js 14 introduced the App Router, revolutionizing how we handle routing in our React applications. Let’s dive deep into the world of App Router and learn how to navigate our apps like a pro. π§
Before we jump into the code, let’s understand what makes the App Router special:
Now, let’s explore how to route to pages in this brave new world.
In Next.js 14, your file structure defines your routes. Here’s the basic structure:
app/
βββ page.js
βββ about/
β βββ page.js
βββ blog/
β βββ page.js
β βββ [slug]/
β βββ page.js
βββ layout.js
In this structure:
/
maps to app/page.js
/about
maps to app/about/page.js
/blog
maps to app/blog/page.js
/blog/my-post
maps to app/blog/[slug]/page.js
Let’s create a simple “About” page:
// app/about/page.js
export default function About() {
return <h1>About Us</h1>;
}
This file automatically creates a route at /about
. No additional configuration needed!
For dynamic routes, use square brackets in your folder names:
// app/blog/[slug]/page.js
export default function BlogPost({ params }) {
return <h1>Blog Post: {params.slug}</h1>;
}
This will match routes like /blog/my-awesome-post
.
To navigate between pages, use the Link
component:
Navigation Component
import Link from 'next/link';
export default function Navigation() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/blog/my-first-post">Blog Post</Link>
</nav>
);
}
For programmatic navigation, use the useRouter
hook:
Programmatic Navigation Component
'use client';
import { useRouter } from 'next/navigation';
export default function NavigateButton() {
const router = useRouter();
return (
<button onClick={() => router.push('/about')}>
Go to About
</button>
);
}
Note the 'use client'
directive. This is because useRouter
is a client-side hook.
One of the coolest features of App Router is nested layouts. Create a layout.js
file in any folder to wrap its children:
Nested Layout Component
// app/blog/layout.js
export default function BlogLayout({ children }) {
return (
<div>
<nav>Blog Navigation</nav>
{children}
</div>
);
}
This layout will apply to all pages under /blog
.
Want to organize your routes without affecting the URL? Use route groups:
app/
βββ (marketing)/
β βββ about/
β β βββ page.js
β βββ contact/
β βββ page.js
βββ (shop)/
βββ products/
β βββ page.js
βββ cart/
βββ page.js
The parentheses ()
create a route group that doesn’t affect the URL structure.
App Router introduces parallel routes, allowing you to render multiple pages in the same layout:
Parallel Routes Layout
// app/dashboard/layout.js
export default function DashboardLayout({ children, analytics, settings }) {
return (
<div>
{children}
{analytics}
{settings}
</div>
);
}
This layout expects page.js
, @analytics/page.js
, and @settings/page.js
in the dashboard
folder.
Want to show a modal for a route without navigating away? Use intercepting routes:
app/
βββ feed/
β βββ page.js
βββ photo/
βββ [...slug]/
β βββ page.js
βββ (.)[...slug]/
βββ page.js // This intercepts /photo routes when already on /feed
The (.)
syntax intercepts same-level routes, while (..)
intercepts one level up, and (...)
from the root.
Customize your 404 and error pages easily:
Not Found Page
// app/not-found.js
export default function NotFound() {
return <h1>404 - Page Not Found</h1>;
}
Error Page
'use client';
// app/error.js
export default function Error({ error, reset }) {
return (
<div>
<h1>Something went wrong!</h1>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
Show loading states with ease:
Loading UI Component
// app/dashboard/loading.js
export default function Loading() {
return <div>Loading...</div>;
}
This will show while the dashboard page or its data is loading.
Need an API route? Use route handlers:
Route Handler
// app/api/hello/route.js
export async function GET() {
return Response.json({ message: 'Hello, Next.js!' });
}
For more control over requests and responses, use middleware:
Middleware
// middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
// Add a header to all responses
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-hello-from-middleware', 'hello');
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
}
export const config = {
matcher: '/api/:path*',
};
This middleware adds a custom header to all API routes.
The Next.js 14 App Router is a game-changer for React routing. It offers a more intuitive, performant, and flexible way to structure your applications. With features like nested layouts, parallel routes, and intercepting routes, you can create complex UIs with ease.
Remember:
Link
for client-side navigationNow go forth and create some next-level Next.js apps! π
Want to dive deeper into Next.js? Check out these electrifying articles: