What's the difference between next/router and next/navigation?

Learn what's the difference between next/router and next/navigation? with practical examples, diagrams, and best practices. Covers javascript, reactjs, next.js development techniques with visual ex...

next/router vs. next/navigation: Understanding Next.js Routing

A conceptual illustration showing two distinct paths diverging, labeled 'next/router' and 'next/navigation', representing the evolution of routing in Next.js. The 'next/router' path shows older React components, while 'next/navigation' shows newer server components. A bridge connects them, symbolizing migration. Clean, modern design with Next.js branding colors.

Explore the key differences between next/router (Pages Router) and next/navigation (App Router) in Next.js, and learn when to use each for effective client-side and server-side navigation.

Next.js has evolved significantly, particularly in its approach to routing. Historically, applications built with the Pages Router used next/router for programmatic navigation. With the introduction of the App Router, a new set of APIs under next/navigation emerged, designed to leverage React Server Components and provide a more unified client-server navigation experience. This article delves into the distinctions between these two modules, helping you understand their core functionalities, use cases, and how they fit into the broader Next.js ecosystem.

The Pages Router and next/router

The Pages Router is the original routing system in Next.js, where files in the pages/ directory automatically become routes. For client-side navigation within a Pages Router application, next/router is the primary module. It provides the useRouter hook (for functional components) and withRouter HOC (for class components) to access the router instance, allowing you to imperatively navigate, refresh, and query route parameters.

import { useRouter } from 'next/router';

function Dashboard() {
  const router = useRouter();

  const navigateToSettings = () => {
    router.push('/settings');
  };

  const refreshPage = () => {
    router.reload();
  };

  return (
    <div>
      <h1>Dashboard</h1>
      <button onClick={navigateToSettings}>Go to Settings</button>
      <button onClick={refreshPage}>Refresh Dashboard</button>
      <p>Current query: {JSON.stringify(router.query)}</p>
    </div>
  );
}

export default Dashboard;

Example of using useRouter in a Pages Router component for navigation and accessing query parameters.

The App Router and next/navigation

The App Router, introduced in Next.js 13, is a new routing paradigm built on React Server Components and nested layouts. It uses a file-system based router where folders define routes and page.js files define UI. For programmatic navigation within the App Router, next/navigation provides a set of client-side hooks like useRouter, usePathname, and useSearchParams. The useRouter hook from next/navigation has a different API and capabilities compared to its next/router counterpart, focusing on client-side transitions and revalidations that work seamlessly with Server Components.

// This is a Client Component - add 'use client' at the top if it were a separate file
'use client';

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

export default function ProductDetail({
  params,
}: { 
  params: { id: string };
}) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const productId = params.id;
  const sortOrder = searchParams.get('sort');

  const navigateToEdit = () => {
    router.push(`/products/${productId}/edit`);
  };

  return (
    <div>
      <h1>Product: {productId}</h1>
      <p>Current path: {pathname}</p>
      <p>Sort order: {sortOrder || 'None'}</p>
      <button onClick={navigateToEdit}>Edit Product</button>
      <button onClick={() => router.refresh()}>Refresh Data</button>
    </div>
  );
}

Using useRouter, usePathname, and useSearchParams from next/navigation in an App Router Client Component.

A comparison table diagram showing 'next/router' on one side and 'next/navigation' on the other. Key features compared include: Router Type (Pages vs. App), React Component Type (Client-side only vs. Client/Server), Primary Hooks (useRouter, withRouter vs. useRouter, usePathname, useSearchParams), Core Functionality (Client-side transitions, imperative navigation vs. Client-side transitions, revalidation, cache management), and Next.js Version (Legacy vs. Modern). Use a clean, two-column layout with clear headings and bullet points for features.

Key differences between next/router and next/navigation.

Choosing the Right Router Module

The choice between next/router and next/navigation is largely dictated by the router you are using. If your application is built with the Pages Router (files in pages/), you will use next/router. If you are building a new application or migrating to the App Router (files in app/), next/navigation is the intended and recommended module for client-side interactions. While it's possible to use next/router in client components within the App Router for certain scenarios (e.g., if you need specific APIs not yet available in next/navigation), it's generally best practice to stick to next/navigation for App Router components to leverage its full capabilities and better integration with Server Components.

1. Step 1

Identify your Next.js project's router type: check for a pages/ directory (Pages Router) or an app/ directory (App Router) at the root.

2. Step 2

For Pages Router projects, import useRouter and other utilities from next/router for all client-side navigation needs.

3. Step 3

For App Router projects, import useRouter, usePathname, and useSearchParams from next/navigation for client-side components.

4. Step 4

If migrating from Pages to App Router, update your navigation logic in client components to use next/navigation APIs where appropriate.