Learn the key differences between next/router and next/navigation in Next.js for streamlined and efficient client-side routing in your web applications.
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.
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:
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:
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!
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:
'use client' to enable client-side functionality.usePathname and useRouter from next/navigation.usePathname./about with a query parameter using router.push.app/about/page.js:
'use client' for client-side logic.useRouter from next/router.useEffect to access the query parameter (message) passed from the Home page.Key Points:
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.'use client' when using client-side features like useRouter and usePathname within the app directory.Here are some additional points to enhance your understanding of next/router and next/navigation:
General Concepts:
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:
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.router.query object automatically parses query parameters from the URL, making them easy to work with.<Link> is preferred for most links, router.push() is useful for redirects based on logic within your components.next/navigation Specifics:
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:
pages directory project, migrating to app and next/navigation might require some refactoring. Assess the complexity and benefits before making the switch.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:
next/navigation.| 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:
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.<Link> component from next/link.Key Considerations:
next/navigation functions are context-aware, crucial for Server Components and data fetching.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.
useRouter hook.
Difference between NextJS Link vs useRouter in Navigating ... | A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
How to test next.js page using useRouter() with jest - JavaScript ... | Hello everyone, after I have my next.js 13 app ready I start with jest testing. I have all necessary dependencies installed and want to begin with a test for my register functionallity. In my register page I use useRouter to push the user after registration to the login page. Here begins the first issue and I have read everything I found in the net, but not found a solution. This is my test: jest.mock('next/navigation', () => ({ useRouter: () => ({ push: jest.fn(), events: { ...
Navigation Guards | Vue Router | The official Router for Vue.js