🐶
Next.js

Next.js: Styling Active Links with useRouter

By Filip on 04/21/2024

Learn how to style an active link based on the current route in Next.js to improve user experience and navigation.

Next.js: Styling Active Links with useRouter

Table of Contents

Introduction

This article will guide you through implementing active links in Next.js, enhancing navigation by visually highlighting the current page. While Next.js lacks a built-in solution, we'll explore effective methods using JavaScript and CSS. The first approach involves the useRouter hook and CSS classes to dynamically style active links. We'll import necessary components, define CSS classes for active and inactive states, and create a NavLink component to apply styling based on the current route. The second method utilizes a custom ActiveLink component with the next-active-link package, simplifying active link management and offering seamless integration with UI libraries like Chakra UI. We'll cover installation, component creation, and usage. Additional considerations include styling customization, mapping links for dynamic rendering, and exploring advanced routing libraries for complex scenarios. By following these steps, you'll effectively implement active link styling in your Next.js applications, improving user experience and navigation clarity.

Step-by-Step Guide

While Next.js doesn't have a built-in solution for active link styling, there are several effective methods to achieve this. Here's a step-by-step guide using JavaScript and incorporating insights from the provided resources:

Method 1: Using the useRouter Hook and CSS Classes

  1. Import Necessary Components:
import Link from 'next/link';
import { useRouter } from 'next/router';
  1. Define CSS Classes:

Create CSS classes for both active and inactive link states. For example:

.nav-link {
  color: #333;
  text-decoration: none;
}

.nav-link.active {
  color: #0070f3;
  font-weight: bold;
}
  1. Implement Active Link Logic:
function NavLink({ href, children }) {
  const router = useRouter();
  const isActive = router.asPath === href;

  return (
    <Link href={href}>
      <a className={`nav-link ${isActive ? 'active' : ''}`}>{children}</a>
    </Link>
  );
}
  1. Use the NavLink Component:
<NavLink href="/">Home</NavLink>
<NavLink href="/about">About</NavLink>

Explanation:

  • We import Link for creating links and useRouter to access the current route information.
  • We define CSS classes to style active and inactive links.
  • The NavLink component checks if the current route (router.asPath) matches the link's href and applies the active class accordingly.
  • Finally, we use the NavLink component to create our navigation links.

Method 2: Using a Custom ActiveLink Component (with Chakra UI Example)

  1. Install next-active-link Package:
npm install next-active-link
  1. Create a Custom ActiveLink Component:
import ActiveLink from 'next-active-link';
import { Link } from '@chakra-ui/react';

function CustomActiveLink({ href, children, ...props }) {
  return (
    <ActiveLink href={href} activeClassName="active" passHref>
      <Link {...props}>{children}</Link>
    </ActiveLink>
  );
}
  1. Use the CustomActiveLink Component:
<CustomActiveLink href="/">Home</CustomActiveLink>
<CustomActiveLink href="/about">About</CustomActiveLink>

Explanation:

  • We install the next-active-link package, which provides a convenient way to manage active links.
  • We create a custom ActiveLink component that wraps the Chakra UI Link component and uses the activeClassName prop from next-active-link.
  • This approach simplifies active link management and integrates seamlessly with Chakra UI.

Additional Considerations:

  • Styling: Customize the CSS classes to match your design preferences.
  • Mapping Links: If you have a list of links, you can map over them and render NavLink or CustomActiveLink components for each item.
  • Advanced Use Cases: For complex scenarios, explore libraries like react-router-dom for more advanced routing and active link management.

By following these steps and adapting them to your specific needs, you can effectively implement active link styling in your Next.js applications.

Code Example

This code provides two methods for implementing active links in Next.js applications. The first method utilizes the useRouter hook and CSS classes to determine and style active links. The second method employs the next-active-link package, showcasing its integration with Chakra UI for styling active links. Both methods offer solutions for visually indicating the current page to users, enhancing navigation experience.

Here's the JavaScript code for the two methods described in the article, along with explanations:

Method 1: Using useRouter and CSS Classes

import Link from 'next/link';
import { useRouter } from 'next/router';

// Define your CSS classes for active and inactive links
// (you can put this in a separate CSS file)
const navLinkStyles = {
  base: 'text-blue-500 hover:text-blue-700',
  active: 'font-bold underline',
};

function NavLink({ href, children }) {
  const router = useRouter();
  const isActive = router.asPath === href;

  // Combine base styles with active styles if the link is active
  const className = `${navLinkStyles.base} ${isActive ? navLinkStyles.active : ''}`;

  return (
    <Link href={href}>
      <a className={className}>{children}</a>
    </Link>
  );
}

// Example usage in your component
<nav>
  <NavLink href="/">Home</NavLink>
  <NavLink href="/about">About</NavLink>
</nav>

Explanation:

  1. Import Components: We import Link for creating Next.js links and useRouter to access the current route information.
  2. CSS Classes: We define CSS classes for the base styling and active state of the links. You can customize these styles as needed.
  3. NavLink Component:
    • The NavLink component takes href and children props for the link's destination and content.
    • It uses useRouter to get the current route (router.asPath).
    • It checks if the current route matches the link's href to determine if the link is active.
    • Based on the active state, it constructs the className string by combining base styles and active styles (if applicable).
    • Finally, it renders a Next.js Link with the calculated className.

Method 2: Using next-active-link (with Chakra UI Example)

import ActiveLink from 'next-active-link';
import { Link } from '@chakra-ui/react';

function CustomActiveLink({ href, children, ...props }) {
  return (
    <ActiveLink href={href} activeClassName="active" passHref>
      <Link {...props}>{children}</Link>
    </ActiveLink>
  );
}

// Example usage (assuming you have Chakra UI set up)
<nav>
  <CustomActiveLink href="/">
    <Text>Home</Text>
  </CustomActiveLink>
  <CustomActiveLink href="/about">
    <Text>About</Text>
  </CustomActiveLink>
</nav>

Explanation:

  1. Install next-active-link: You'll need to install this package using npm install next-active-link.
  2. CustomActiveLink Component:
    • This component takes href, children, and any additional props to pass to the Chakra UI Link component.
    • It uses ActiveLink from next-active-link and provides the href and activeClassName (which should match your CSS class for active links).
    • The passHref prop ensures that the href is passed to the underlying a tag for proper link behavior.
    • Inside, it renders a Chakra UI Link with the provided children and props.

Choosing a Method:

  • Method 1 is more lightweight if you only need basic active link styling and don't want to add an external dependency.
  • Method 2 is convenient if you're already using Chakra UI or want more advanced active link management features provided by next-active-link.

Additional Notes

  • Exact Matching: In some cases, you might want to ensure exact path matching for active links. For example, if you have a link to /blog and another to /blog/post-1, you might not want the /blog link to be active when you're on /blog/post-1. You can achieve this by using the exact prop with next-active-link or by implementing your own logic to compare paths more precisely.
  • Nested Routes: When dealing with nested routes, you might need to adjust your active link logic to consider the parent routes as well. This could involve checking if the current route starts with the link's href or using a library like path-to-regexp for more complex matching.
  • Dynamic Routes: If you're using dynamic routes in Next.js (e.g., pages/blog/[slug].js), you'll need to make sure your active link logic can handle the dynamic segments. This might involve extracting the slug from the current route and comparing it to the link's href.
  • Performance: For large applications with many links, consider the performance implications of your active link implementation. Avoid unnecessary re-renders by using techniques like memoization or optimizing your CSS selectors.
  • Accessibility: Ensure that your active link styling is accessible to users with disabilities. Use sufficient color contrast and consider providing alternative visual cues, such as underlines or icons, to indicate the active state.
  • Server-Side Rendering (SSR): If you're using SSR, make sure your active link logic works correctly on both the server and the client. This might involve using a library that supports SSR or implementing your own logic to handle the different environments.
  • Testing: Write tests to ensure that your active link implementation works as expected under different conditions, including different routes, dynamic segments, and edge cases.

Alternatives and Advanced Techniques

  • CSS-in-JS Libraries: Consider using CSS-in-JS libraries like styled-components or Emotion to manage your active link styles. These libraries can provide more flexibility and maintainability for your styling.
  • State Management Libraries: For complex applications, you might want to manage the active link state using a state management library like Redux or Zustand. This can help centralize the state and make it easier to share across different components.
  • Custom Hooks: Create custom hooks to encapsulate your active link logic and make it reusable across different parts of your application. This can improve code organization and reduce duplication.

By considering these additional notes and exploring alternative techniques, you can implement active links in your Next.js applications effectively and ensure a seamless user experience.

Summary

Method Description Key Steps Benefits Drawbacks
Using useRouter Hook and CSS Classes Manually manage active state with JavaScript and CSS. 1. Import Link and useRouter. 2. Define CSS classes for active/inactive states. 3. Create NavLink component to apply classes based on route. 4. Use NavLink for navigation. Simple and flexible. No external dependencies. Requires more code and manual state management.
Using next-active-link Package Leverage a dedicated package for active link management. 1. Install next-active-link. 2. Create custom component with ActiveLink and desired UI library (e.g., Chakra UI). 3. Use custom component for navigation. Easier to implement and maintain. Integrates with UI libraries. Adds an external dependency.

Conclusion

Implementing active links in your Next.js applications is crucial for providing a clear and intuitive navigation experience for your users. While Next.js doesn't offer a built-in solution, the methods outlined in this guide empower you to achieve this functionality effectively. Whether you choose the flexibility of the useRouter hook and CSS classes or the convenience of the next-active-link package, you can tailor the approach to your specific project requirements and preferences.

Remember to consider additional factors such as exact path matching, nested routes, dynamic routing, performance optimization, accessibility, server-side rendering, and thorough testing to ensure a robust and user-friendly implementation. By carefully addressing these aspects, you can create a navigation system that guides users seamlessly through your application, enhancing their overall experience.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait