DEV Community

Cover image for Active Links in Next JS and React Js
Ishan Sen
Ishan Sen

Posted on

Active Links in Next JS and React Js

Hi there! 🌟

I’m new to Next.js, and recently, I was diving deep into the concept of active links. I wanted to make sure that the current page's link gets a special styling to indicate it's active. While scouring the internet, I found plenty of videos and articles about styling active links. However, there wasn't much guidance on determining if a link is active or not. So, I decided to write my own code to solve this problem.

Defining the Problem

  1. The code should not require me to change my home link from '/' to something like '/home'.
  2. The code should also work for nested links like '/troubleshoot/logs'.

Prerequisite code

You need pathname to check the active link.
If you are using Next Js:

import { usePathname } from "next/navigation"
const pathname = usePathname()
Enter fullscreen mode Exit fullscreen mode

If you are using React Js:

import { useLocation } from "react-router-dom"
const { pathname } = useLocation()
Enter fullscreen mode Exit fullscreen mode

We will create a checkActive function which will take the href that we need to check and return a boolean value.

const checkActive = ( href ) => {
    // Code to check if link is active or not.
}
Enter fullscreen mode Exit fullscreen mode

Before I share my solution, let’s look at some common methods I came across and why they didn’t quite work for me.

1. Using pathname.startsWith

This method was suggested by the tutorial I was following.

const checkActive = ( href ) => {
    return pathname.startsWith( href )
}
Enter fullscreen mode Exit fullscreen mode

Problem:
In this method your home page has href = '/', it will always be active.

Image showing problem with using pathname.startsWith()

2. Using pathname.endsWith

In the comments of the same tutorial, someone suggested using pathname.endsWith instead.

const checkActive = ( href ) => {
    return pathname.startsWith( href )
}
Enter fullscreen mode Exit fullscreen mode

Problem:
This method will work for simple links like /troubleshoot but fail if you have nested links like /troubleshoot/logs.

Image showing problem with using pathname.endsWith()

3. Hardcoding

Another approach some developers take is hardcoding the active state. This might look something like this:

<Link href="/about" className = {`${pathname === "/about" ? "bg-primary" : "bg-secondary"} text-black`} />
<Link href="/troubleshoot" className = {`${pathname === "/troubleshoot" ? "bg-primary" : "bg-secondary"} test-black`} />
Enter fullscreen mode Exit fullscreen mode

Problem:
Hardcoding the active state for each link can get messy and is not scalable, especially if you have a large number of routes. It’s also prone to human error.

My Solution

After some experimentation, I came up with a solution that works well for me. It checks the pathname more precisely to ensure accuracy. This is just a modified version of the pathname.startsWith() method.

const checkActive = ( href ) => {
    const n = href.length
    // Check if the pathname starts with the link's href
    if (pathname.startsWith(href)) {
      // If the pathname is longer than the link's href and the character after the link's href is a '/', then the link is considered active.
      if (pathname.length > n && pathname[n] === "/") return true

      // If the pathname is exactly the same length as the link's href, then the link is considered active.
      if (pathname.length == n) return true
    }
    return false
  }

Enter fullscreen mode Exit fullscreen mode

This method accurately identifies active links without the pitfalls of the other methods.

Image showing my solution working for all cases

Bonus Method

This method was given to me by chatGPT when I was looking for solutions other than mine. This method uses regex which I don't find intuitive but I have added it here if someone prefers this more.

const checkActive = ( href ) => {
     return pathname === href || pathname.match(new RegExp( `^${href}(?:/|$)` ));
}
Enter fullscreen mode Exit fullscreen mode

This will also work for all the cases that I mentioned in this article.

I hope this helps you manage active links more effectively in your Next.js projects.

Comment below if you found this helpful or if you have some other method you use. Happy coding! πŸš€

Top comments (0)