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.