Active Links in Next JS and React Js

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

The code should not require me to change my home link from ‘/’ to something like ‘/home’.
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()

If you are using React Js:

import { useLocation } from react-router-dom
const { pathname } = useLocation()

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.
}

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 )
}

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

2. Using pathname.endsWith

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

const checkActive = ( href ) => {
return pathname.startsWith( href )
}

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

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`} />

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
}

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

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}(?:/|$)` ));
}

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! 🚀