
Amit Hariyale
Full Stack Web Developer, Gigawave
Full Stack Web Developer, Gigawave
Next.js revolutionized web development with its file-based routing system that automatically maps your directory structure to application routes. This guide explores both fundamental concepts and advanced routing patterns to help you build complex applications with confidence.
Next.js automatically maps files in the app
directory to routes:
1app/
2├── page.tsx → /
3├── about/
4│ └── page.tsx → /about
5├── blog/
6│ ├── page.tsx → /blog
7│ └── [slug]/
8│ └── page.tsx → /blog/:slug
9└── dashboard/
10 └── settings/
11 └── page.tsx → /dashboard/settings
Create shared UI with layout.tsx
andtemplate.tsx
files:
1return function RootLayout({
2 children,
3}: {
4 children: React.ReactNode;
5}) {
6 return (
7 <html lang="en">
8 <body>
9 <Header />
10 <main>{children}</main>
11 <Footer />
12 </body>
13 </html>
14 );
15}
Capture variable path segments using square brackets:
1return function BlogPost({
2 params,
3}: {
4 params: { slug: string };
5}) {
6 return <h1>Blog Post: {params.slug}</h1>;
7}
8
9// Generate static paths at build time
10export async function generateStaticParams() {
11 const posts = await getBlogPosts();
12 return posts.map((post) => ({ slug: post.slug }));
13}
Organize routes without affecting URL structure using parentheses:
1app/
2├── (marketing)/
3│ ├── about/
4│ ├── pricing/
5│ └── layout.tsx # Marketing-specific layout
6└── (app)/
7 ├── dashboard/
8 ├── settings/
9 └── layout.tsx # App-specific layout
Render multiple pages in the same layout simultaneously:
1return function Layout({
2 children,
3 analytics,
4 notifications,
5}: {
6 children: React.ReactNode;
7 analytics: React.ReactNode;
8 notifications: React.ReactNode;
9}) {
10 return (
11 <div className="grid grid-cols-3">
12 <div className="col-span-2">{children}</div>
13 <div className="grid grid-rows-2 gap-4">
14 <div>{analytics}</div>
15 <div>{notifications}</div>
16 </div>
17 </div>
18 );
19}
Show a route in a modal while preserving the context:
1app/
2├── @modal/
3│ └── (.)photo/
4│ └── [id]/
5│ └── page.tsx # Intercepted route
6└── photo/
7 └── [id]/
8 └── page.tsx # Full page route
1import PhotoModal from "@/app/@modal/(.)photo/[id]/page";
2
3return function PhotoPage({
4 params: { id },
5}: {
6 params: { id: string };
7}) {
8 const photo = getPhoto(id);
9
10 return (
11 <>
12 <PhotoModal photo={photo} />
13 {/* Full page content */}
14 </>
15 );
16}
Render different UIs based on authentication state:
1import { getCurrentUser } from "@/lib/auth";
2
3return async function Layout({
4 user,
5 guest,
6}: {
7 user: React.ReactNode;
8 guest: React.ReactNode;
9}) {
10 const session = await getCurrentUser();
11
12 return (
13 <div>
14 <DashboardHeader />
15 {session ? user : guest}
16 </div>
17 );
18}
Protect routes before they render:
1import { NextResponse } from 'next/server';
2import type { NextRequest } from 'next/server';
3
4export function middleware(request: NextRequest) {
5 const token = request.cookies.get('auth-token')?.value;
6
7 // Redirect unauthenticated users
8 if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
9 return NextResponse.redirect(new URL('/login', request.url));
10 }
11
12 // Add security headers to all routes
13 const response = NextResponse.next();
14 response.headers.set('X-Content-Type-Options', 'nosniff');
15 return response;
16}
17
18export const config = {
19 matcher: ['/dashboard/:path*'],
20};
Next.js Routing Features | Next.js provides a rich set of routing features to create dynamic and interactive web experiences. |
---|---|
Route Handlers | API endpoints using Web Request/Response APIs |
Server Actions | Call server functions directly from components |
Dynamic Route Segments | Catch-all [...slug] and optional [[...slug]] routes |
Internationalization | Locale-based routing with next-intl |
Custom 3D Route Transitions | Using Framer Motion and Three.js |
Create API endpoints alongside your routes:
1import { NextResponse } from 'next/server';
2
3export async function GET() {
4 const users = await db.user.findMany();
5 return NextResponse.json(users);
6}
7
8export async function POST(request: Request) {
9 const data = await request.json();
10 const newUser = await db.user.create({ data });
11 return NextResponse.json(newUser, { status: 201 });
12}
Advanced pattern matching with catch-all routes:
1return function CategoryPage({
2 params,
3}: {
4 params: { category: string[] };
5}) {
6 // URL: /shop/electronics/phones
7 // params: { category: ['electronics', 'phones'] }
8
9 return <ProductGrid category={params.category} />;
10}
Next.js routing system provides an elegant solution that scales from simple websites to complex applications. By mastering both fundamental concepts and advanced patterns like parallel routes and route interception, you can create intuitive navigation experiences that delight users.
Remember: The file-based routing system is just the beginning - combine it with Next.js' data fetching strategies and rendering modes to build truly powerful applications.