Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Mastering Next.js 14 App Router: The Ultimate Guide to Page Routing

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. 🧭

The App Router Revolution

Before we jump into the code, let’s understand what makes the App Router special:

  1. File-based routing
  2. Nested layouts
  3. Server Components by default
  4. Improved performance
  5. More intuitive API

Now, let’s explore how to route to pages in this brave new world.

File-System Based Routing

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

Creating a Basic Route

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!

Dynamic Routes

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.

Linking Between Pages

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>
  );
}

Programmatic Navigation

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.

Nested Layouts

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.

Route Groups

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.

Parallel Routes

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.

Intercepting Routes

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.

Not Found and Error Pages

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>
  );
}

Loading UI

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.

Route Handlers

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!' });
}

Middleware

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.

Conclusion

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:

  • Your file structure is your routing structure
  • Use Link for client-side navigation
  • Leverage layouts for shared UI
  • Explore advanced features like parallel and intercepting routes

Now go forth and create some next-level Next.js apps! πŸš€

Want to dive deeper into Next.js? Check out these electrifying articles:

Leave a Reply

Your email address will not be published. Required fields are marked *