Next JS Linking and Navigations
In Next.js, linking and navigating between pages is essential to creating a dynamic web application. Next.js provides tools for client-side navigation that are optimized for performance and user experience. Below is a detailed explanation of the various ways to implement linking and navigation in a Next.js application.
1. Using the <Link>
Component
The primary way to navigate between pages in Next.js is by using the <Link>
component, which is similar to an HTML anchor (<a>
), but optimized for client-side navigation. This allows Next.js to load the content without a full page reload, providing a faster and smoother user experience.
- Example of using the
<Link>
component:import Link from 'next/link'; const HomePage = () => { return ( <div> <h1>Welcome to the Homepage!</h1> <Link href="/about"> <a>About Us</a> </Link> </div> ); }; export default HomePage;
a. Features of the <Link>
Component
Client-Side Navigation: Using
<Link>
enables client-side transitions between routes. This makes navigation faster since the JavaScript code already knows which component to load.Prefetching: By default, Next.js automatically prefetches links in the viewport when they are about to enter. This means that when users navigate, the next page is already loaded in the background.
<Link href="/about"> <a>About Us</a> {/* You can omit the <a> tag in Next.js 13 or later */} </Link>
Replace Navigation: The
<Link>
component supports replacing the current history state instead of pushing a new entry using thereplace
prop.<Link href="/about" replace> <a>About Us</a> </Link>
Scroll Control: The
scroll
prop can be used to prevent the default behavior of scrolling to the top after navigation.<Link href="/about" scroll={false}> <a>About Us</a> </Link>
b. New Usage in Next.js 13
In Next.js 13, the href
attribute can be directly used without a nested <a>
tag:
<Link href="/about">About Us</Link>
2. Programmatic Navigation Using useRouter
The useRouter
hook from Next.js allows you to navigate programmatically, which is particularly useful for dynamic routing or triggering navigation based on user actions.
- Example of
useRouter
:import { useRouter } from 'next/router'; const HomePage = () => { const router = useRouter(); const navigateToAbout = () => { router.push('/about'); }; return ( <div> <h1>Welcome to the Homepage!</h1> <button onClick={navigateToAbout}>Go to About Page</button> </div> ); }; export default HomePage;
a. Methods in useRouter
router.push(url, as, options)
: Navigate to a new URL. You can pass a string URL or an object with apathname
andquery
.router.push('/about'); router.push({ pathname: '/about', query: { name: 'John' } });
router.replace(url, as, options)
: Similar topush()
, but replaces the current history entry instead of adding a new one.router.back()
: Navigate to the previous page in the user's history.router.back();
router.prefetch(url)
: Prefetches the page if possible to make navigation faster.
3. Navigating with HTML <a>
Tags
In some cases, you might still use an HTML <a>
tag for external links or when you want the navigation to perform a full page reload.
- External link example:
const HomePage = () => ( <a href="https://example.com" target="_blank" rel="noopener noreferrer"> Visit Example </a> );
Note: When linking between pages inside a Next.js app, it’s better to use <Link>
to maintain a client-side experience. Using a standard <a>
will cause a full page reload.
4. Navigation Options and Enhancements
a. Customizing Link Behavior
- Handling Active Links: You can add custom styles or classes to indicate that a link is "active" when the current route matches its destination.
import { useRouter } from 'next/router'; import Link from 'next/link'; const Navigation = () => { const router = useRouter(); return ( <nav> <Link href="/"> <a className={router.pathname == '/' ? 'active' : ''}>Home</a> </Link> <Link href="/about"> <a className={router.pathname == '/about' ? 'active' : ''}>About</a> </Link> </nav> ); }; export default Navigation;
b. Shallow Routing
- Shallow routing allows you to change the URL without running
getServerSideProps
,getStaticProps
, orgetInitialProps
again.
This is useful for maintaining state between route changes without triggering data fetching.router.push('/about?section=team', undefined, { shallow: true });
5. Middleware for Routing Control
Middleware in Next.js allows you to control routing behavior at a global level. For example, you can use it to redirect users based on authentication status.
- Example of redirecting unauthenticated users:
// middleware.js import { NextResponse } from 'next/server'; export function middleware(req) { const { pathname } = req.nextUrl; // Redirect to login if not authenticated if (pathname.startsWith('/dashboard')) { const authenticated = false; // Replace with actual authentication check if (!authenticated) { return NextResponse.redirect('/login'); } } }
Summary
- Linking with
<Link>
: The<Link>
component is the main way to navigate between pages in Next.js. It is optimized for client-side transitions and prefetching. - Programmatic Navigation with
useRouter
: Use theuseRouter
hook for navigation triggered by JavaScript functions or user actions. - HTML
<a>
Tag: Best for external links or full page reloads. - Handling Active Links: Use
useRouter
to add active link styles. - Shallow Routing: Change the URL without triggering data fetching functions.
- Middleware: Control navigation and implement redirections globally.
These tools make Next.js navigation seamless and allow for flexibility in building a fast and intuitive user experience.