Active Links in Next JS and React Js
Tags: webdev, nextjs, javascript, programming
Published: 2024-07-05 09:56:00

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:

```javascript
import { usePathname } from "next/navigation"
const pathname = usePathname()
```
If you are using React Js:

```javascript
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.
```javascript
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.

```javascript
const checkActive = ( href ) => {
    return pathname.startsWith( href )
}
```
**Problem:** 
In this method your home page has `href = '/'`, it will always be active.

![Image showing problem with using pathname.startsWith()](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvppo4z1hp595q6htusy.jpg)

## 2. Using `pathname.endsWith`
In the comments of the same tutorial, someone suggested using pathname.endsWith instead. 
```javascript
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`.

![Image showing problem with using pathname.endsWith()](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqddcsapoycq8023qhy8.jpg)

## 3. Hardcoding
Another approach some developers take is hardcoding the active state. This might look something like this:
```javascript
<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.
```javascript
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.

![Image showing my solution working for all cases](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0ewmnpeg3lzkv3n16ww.jpg)

## 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.
```javascript
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! 🚀