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 the replace 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 a pathname and query.
    router.push('/about'); router.push({ pathname: '/about', query: { name: 'John' } });
  • router.replace(url, as, options): Similar to push(), 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, or getInitialProps again.
    router.push('/about?section=team', undefined, { shallow: true });
    This is useful for maintaining state between route changes without triggering data fetching.

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 the useRouter 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.