🐶
Next.js

next/router vs next/navigation: Key Differences Explained

By Filip on 10/05/2024

Learn the key differences between next/router and next/navigation in Next.js for streamlined and efficient client-side routing in your web applications.

next/router vs next/navigation: Key Differences Explained

Table of Contents

Introduction

In the world of Next.js, efficient navigation is key to building seamless user experiences. This article will guide you through the intricacies of navigation in Next.js, focusing on two essential tools: next/router and next/navigation. We'll explore their core functionalities, compare their strengths, and provide clear examples to illustrate their usage. Whether you're working with the traditional pages directory or the newer app directory, understanding these navigation tools will empower you to build robust and performant Next.js applications.

Step-by-Step Guide

Let's break down navigation in Next.js, focusing on next/router and next/navigation.

Understanding the Basics

  • Navigation in Single-Page Applications (SPAs): Next.js, like other modern web frameworks, builds SPAs. This means instead of loading entirely new pages from the server, we dynamically update parts of the current page. This creates a smoother, faster user experience.

  • Client-Side Routing: To manage these in-app transitions, we use client-side routing. This is where next/router and next/navigation come in.

next/router: The Traditional Approach

  • Purpose: next/router has been the go-to for handling routing in Next.js for a long time. It's great for:

    • Accessing route information (current path, query parameters).
    • Programmatically navigating between pages.
    • Listening for route change events.
  • Example:

    import { useRouter } from 'next/router';
    
    function MyComponent() {
      const router = useRouter();
    
      const handleClick = () => {
        router.push('/about?name=John'); // Navigate to /about with a query parameter
      };
    
      return (
        <button onClick={handleClick}>Go to About Page</button>
      );
    }

next/navigation: The Modern Solution

  • Introduction: next/navigation is a newer addition to Next.js, specifically designed for the app directory (a more recent way to structure Next.js projects).

  • Key Features:

    • Improved Data Fetching: Works seamlessly with Server Components for efficient data loading during transitions.
    • Layout and Route Caching: Helps optimize performance by intelligently caching parts of your application.
  • Example:

    'use client'; // Required for client-side functionality in the app directory
    
    import { usePathname, useRouter } from 'next/navigation';
    
    function MyComponent() {
      const pathname = usePathname();
      const router = useRouter();
    
      const handleClick = () => {
        router.push('/about'); 
      };
    
      return (
        <div>
          <p>Current Path: {pathname}</p>
          <button onClick={handleClick}>Go to About Page</button>
        </div>
      );
    }

When to Use What

  • App Directory: If you're starting a new project with the app directory structure, next/navigation is the recommended choice. It's designed to take full advantage of the new architecture.

  • Pages Directory: For existing projects using the pages directory, next/router continues to be a reliable option.

Important Considerations

  • Server vs. Client: Remember that Next.js applications run both on the server and in the browser. next/navigation provides functions that are aware of this context, which is crucial for Server Components and data fetching optimizations.

  • Link Component: For declarative navigation (creating links within your UI), the <Link> component from next/link is generally preferred over router.push() in both pages and app directories.

Let me know if you'd like a deeper dive into a specific aspect, like data fetching during navigation or how to handle redirects!

Code Example

This code example demonstrates navigation in a Next.js application using both next/router and next/navigation. It includes a simple layout with navigation links, a home page that programmatically navigates to an about page with a query parameter, and an about page that reads the query parameter. The example highlights the use of use client for client-side functionality in the app directory and showcases basic navigation and query parameter handling.

This example demonstrates both next/router and next/navigation in action.

Project Structure (using app directory):

app/
├── about/
│   └── page.js
├── layout.js
└── page.js

1. app/layout.js:

import Link from 'next/link';

export default function Layout({ children }) {
  return (
    <div>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </nav>
      {children}
    </div>
  );
}

2. app/page.js (using next/navigation):

'use client';

import { usePathname, useRouter } from 'next/navigation';

export default function HomePage() {
  const pathname = usePathname();
  const router = useRouter();

  const handleClick = () => {
    router.push('/about?message=Hello from Home');
  };

  return (
    <div>
      <h1>Home Page</h1>
      <p>Current Path: {pathname}</p>
      <button onClick={handleClick}>Go to About (with query)</button>
    </div>
  );
}

3. app/about/page.js (using next/router):

'use client';

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function AboutPage() {
  const router = useRouter();

  useEffect(() => {
    // Access query parameters
    const { message } = router.query;
    if (message) {
      console.log('Message from query:', message); 
    }
  }, [router.query]);

  return (
    <div>
      <h1>About Page</h1>
    </div>
  );
}

Explanation:

  • app/layout.js: Sets up a simple navigation bar using next/link for declarative navigation.
  • app/page.js:
    • Uses 'use client' to enable client-side functionality.
    • Imports usePathname and useRouter from next/navigation.
    • Displays the current pathname using usePathname.
    • Programmatically navigates to /about with a query parameter using router.push.
  • app/about/page.js:
    • Uses 'use client' for client-side logic.
    • Imports useRouter from next/router.
    • Uses useEffect to access the query parameter (message) passed from the Home page.

Key Points:

  • This example showcases both next/router and next/navigation working together in an app directory project.
  • next/navigation is preferred for new projects using the app directory, while next/router remains valid for existing pages directory projects.
  • Remember to use 'use client' when using client-side features like useRouter and usePathname within the app directory.
  • This example demonstrates basic navigation and query parameter handling. You can explore more advanced features like data fetching during navigation and redirects in the Next.js documentation.

Additional Notes

Here are some additional points to enhance your understanding of next/router and next/navigation:

General Concepts:

  • Purpose of Client-Side Routing: The primary goal is to avoid full page reloads, making web apps feel faster and more responsive. This is achieved by only updating the necessary parts of the DOM.
  • History Management: Both next/router and next/navigation interact with the browser's history API. This allows for back/forward button functionality and maintaining correct state when navigating.

next/router Specifics:

  • Events: next/router provides events like routeChangeStart, routeChangeComplete, and routeChangeError for hooking into the navigation lifecycle. This is useful for tasks like showing loading indicators or handling errors.
  • Query Parameter Parsing: The router.query object automatically parses query parameters from the URL, making them easy to work with.
  • Programmatic Redirects: While <Link> is preferred for most links, router.push() is useful for redirects based on logic within your components.

next/navigation Specifics:

  • Server Component Awareness: A major advantage is its tight integration with Server Components. This enables data fetching to happen on the server during navigation, improving performance and SEO.
  • useSearchParams: Similar to router.query, this hook (available in next/navigation) provides a way to read and modify URL search parameters.
  • redirect Function: For redirects within Server Components, the redirect function from next/navigation is the recommended approach.

Choosing the Right Tool:

  • Migration: If you have an existing pages directory project, migrating to app and next/navigation might require some refactoring. Assess the complexity and benefits before making the switch.
  • Learning Curve: next/navigation introduces new concepts that might take some time to grasp, especially for developers new to Server Components and the app directory.

Beyond the Basics:

  • Data Fetching: Explore how to fetch data efficiently during navigation using Server Components and next/navigation.
  • Authentication: Learn how to protect routes and handle authentication redirects using middleware or other techniques.
  • Advanced Routing: Dive into more complex routing scenarios like nested layouts, dynamic routes, and route transitions.

Summary

Feature next/router next/navigation
Directory Compatibility pages app
Recommended Use Existing projects New projects
Data Fetching Optimization Not directly integrated Seamless with Server Components
Layout/Route Caching Not directly supported Built-in optimization
Accessing Route Info router.pathname, router.query usePathname()
Programmatic Navigation router.push(), router.replace() router.push(), router.replace()
Route Change Events router.events.on('routeChangeStart', ...) Not directly supported

Summary:

  • Both next/router and next/navigation handle client-side routing in Next.js SPAs.
  • next/router is the traditional approach, suitable for projects using the pages directory.
  • next/navigation is a modern solution designed for the app directory, offering better integration with Server Components and performance optimizations.
  • For declarative navigation, use the <Link> component from next/link.

Key Considerations:

  • next/navigation functions are context-aware, crucial for Server Components and data fetching.
  • Choose the appropriate approach based on your project's directory structure and desired features.

Conclusion

In conclusion, mastering navigation in Next.js is crucial for crafting exceptional user experiences. Whether you're leveraging the established next/router within the pages directory or harnessing the power of next/navigation in the app directory, understanding their nuances empowers you to build high-performance applications. As you delve deeper into Next.js, explore advanced concepts like data fetching during navigation, authentication, and intricate routing scenarios to unlock the full potential of this framework. By mastering these tools, you'll be well-equipped to create seamless and efficient navigation experiences for your users.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait