Navigating Between Pages in Next.js

ATANU DAS Avatar
Navigating Between Pages in Next.js

Navigating Between Pages in Next.js is a fundamental aspect of web development, and in Next.js, this process is made efficient with several advanced features. This chapter focuses on adding navigation links to your dashboard layout, ensuring seamless transitions without full page refreshes. We will delve into the use of the next/link component, displaying active links using the usePathname() hook, and understanding how navigation works in Next.js.

Table of content

Introduction

Efficient navigation is crucial for a smooth user experience in any web application. In this chapter, we explore the tools and techniques provided by Next.js to optimize page navigation, minimizing disruptions and enhancing performance.

Traditional HTML navigation relies on the <a> element, which causes a full page reload with each navigation. In Next.js, the <Link> component is used to handle client-side navigation seamlessly.

Implementing the <Link> Component

To implement the <Link> component, follow these steps:

  • Import the Component: Begin by importing the Link component from next/link in your navigation file.
import Link from 'next/link';
  • Replace <a> Tags: Replace your existing <a> tags with <Link>. Here is an example code snippet for nav-links.tsx:
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';

export default function NavLinks() {
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

This approach ensures that navigating between the pages does not cause a full page reload, resulting in a smoother user experience.

To enhance user navigation, it’s helpful to highlight the currently active link. This can be achieved using the usePathname() hook.

Implementing usePathname()

  • Convert to a Client Component: Add the directive "use client" at the top of your file and import usePathname from next/navigation.
'use client';

import { usePathname } from 'next/navigation';
  • Determine Active Link: Inside your NavLinks component, use the pathname to determine which link is active.
export default function NavLinks() {
  const pathname = usePathname();
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className={clsx(
              'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
              { 'bg-sky-100 text-blue-600': pathname === link.href }
            )}
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

The clsx library is used to conditionally apply styles, highlighting the active link.

How Navigation Works in Next.js

Next.js optimizes navigation through automatic code-splitting and prefetching, ensuring efficient performance and a seamless user experience.

Automatic Code-Splitting and Prefetching

Next.js automatically splits your application code by route segments, unlike traditional single-page applications where all code is loaded initially. This isolation ensures that only the necessary code is loaded for each route.

When <Link> components are rendered, Next.js prefetches the linked routes in the background. This preloading ensures near-instant transitions when users navigate to those routes.

Next.js employs a hybrid approach for routing and navigation, combining server-side and client-side techniques.

Code Splitting

Code splitting reduces the amount of code transferred and executed, enhancing performance. Next.js server components automatically split code by route segments, loading only the required code on navigation.

Prefetching

Prefetching routes can be done in two ways:

  1. Automatic Prefetching: The <Link> component prefetches routes as they become visible in the viewport.
  2. Programmatic Prefetching: Use the useRouter hook’s router.prefetch() method to prefetch routes programmatically.

Caching

Next.js employs an in-memory client-side cache, storing the payload of prefetched routes and visited segments. This cache reduces server requests and data transfer on navigation, improving performance.

Partial Rendering

Partial rendering only re-renders route segments that change, preserving shared segments. This reduces data transfer and execution time, enhancing performance.

Soft Navigation

Soft navigation ensures only the changed route segments re-render, preserving client React state. This approach prevents full page reloads and maintains a smooth navigation experience.

Back and Forward Navigation

Next.js maintains scroll positions for backward and forward navigation, reusing route segments from the router cache to enhance performance.

Routing Between pages/ and app/

When migrating from pages/ to app/, Next.js handles hard navigation between the two, leveraging probabilistic checking to minimize false positives. This ensures smooth transitions and maintains performance.

Highlighting active links enhances user experience by clearly indicating the current page. Using the usePathname() hook and conditional styling with the clsx library, active links can be visually distinguished.

import { usePathname } from 'next/navigation';
import clsx from 'clsx';

export default function NavLinks() {
  const pathname = usePathname();
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className={clsx(
              'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
              { 'bg-sky-100 text-blue-600': pathname === link.href }
            )}
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

Conclusion

Navigating between pages in Next.js is optimized through features like code splitting, prefetching, caching, and partial rendering. By leveraging these tools, you can ensure a smooth and efficient user experience in your web application.

FAQs

How does the <Link> component in Next.js differ from the traditional <a> tag?

The <Link> component in Next.js allows for client-side navigation without causing a full page reload, unlike the traditional <a> tag, which triggers a full page refresh.

What is automatic code-splitting in Next.js?

Automatic code-splitting in Next.js divides the application code into smaller bundles by route segments, loading only the necessary code for each route, improving performance.

How does prefetching enhance navigation in Next.js?

Prefetching in Next.js preloads route data in the background as links become visible in the viewport, ensuring near-instant transitions when users navigate to those routes.

What is the purpose of the usePathname() hook in Next.js?

The usePathname() hook in Next.js retrieves the current path, allowing developers to implement features like highlighting the active link based on the user’s current location.

How does caching work in Next.js navigation?

Next.js uses an in-memory client-side cache to store prefetched route segments and visited routes, reducing server requests and data transfer on navigation.

What is partial rendering in Next.js?

Partial rendering in Next.js re-renders only the route segments that change on navigation, preserving shared segments and reducing data transfer and execution time.

Next topics

Read next blog to create next.js app Creating Layouts and Pages on Next.js

References

,

Leave a Reply

Your email address will not be published. Required fields are marked *