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! π
Top comments (0)