• Next.js
  • Routing
  • Web Development

Mastering Next.js Routing From Basics to Advanced Patterns

Amit Hariyale

Amit Hariyale

Full Stack Web Developer, Gigawave

10 min read · June 14, 2025

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.

Why Next.js Routing Stands Out

  • Zero configuration required
  • Automatic code splitting
  • Nested routing support
  • Built-in loading states
  • Advanced patterns for complex UIs
Did You Know?Next.js routes can render as static HTML, server-side rendered, or client-side rendered - all in the same application!

Basic Routing Fundamentals

File Structure = URL Path

Next.js automatically maps files in the app directory to routes:

Project Structure
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

Layouts and Templates

Create shared UI with layout.tsx andtemplate.tsx files:

app/layout.tsx
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}

Dynamic Routes

Capture variable path segments using square brackets:

app/blog/[slug]/page.tsx
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}

Route Groups

Organize routes without affecting URL structure using parentheses:

Project Structure
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

Advanced Routing Patterns

Parallel Routes

Render multiple pages in the same layout simultaneously:

app/dashboard/layout.tsx
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}

Intercepted Routes

Show a route in a modal while preserving the context:

Project Structure
1app/ 2├── @modal/ 3│ └── (.)photo/ 4│ └── [id]/ 5│ └── page.tsx # Intercepted route 6└── photo/ 7 └── [id]/ 8 └── page.tsx # Full page route
app/photo/[id]/page.tsx
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}

Conditional Routes

Render different UIs based on authentication state:

app/dashboard/layout.tsx
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}

Route Protection with Middleware

Protect routes before they render:

middleware.ts
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};

Advanced Routing Techniques

Next.js Routing FeaturesNext.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

Custom Route Handlers

Create API endpoints alongside your routes:

app/api/users/route.ts
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}

Dynamic Route Segments

Advanced pattern matching with catch-all routes:

app/shop/[...category]/page.tsx
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}

Routing Best Practices

  • Use route groups for organization
  • Implement middleware for cross-cutting concerns
  • Prefer generateStaticParams for SSG
  • Use parallel routes for complex dashboards
  • Add custom 404 and error pages

Pro Tips

  • Use the 'useSelectedLayoutSegment' hook to create responsive layouts
  • Combine route intercepting with history state for seamless modal experiences
  • Leverage route groups to split CSS bundles by section
  • Use middleware for A/B testing and feature flags
  • Implement skeleton screens with loading.tsx for better UX

Essential Resources

Final Thoughts

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.

Next Blog

Implementing Role-Based Access Control in Next.js Using Middleware

Read Next