How to target the active Link in Next.js like they way we do it in React-Router-4? Meaning, give the active link a class when its route is active?
19 Answers
A simple solution based on the useRouter
hook:
import Link from "next/link";
import { useRouter } from "next/router";
export const MyNav = () => {
const router = useRouter();
return (
<ul>
<li className={router.pathname == "/" ? "active" : ""}>
<Link href="/">home</Link>
</li>
<li className={router.pathname == "/about" ? "active" : ""}>
<Link href="/about">about</Link>
</li>
</ul>
);
};
You could also use router.asPath
instead of router.pathname
if you want to include the url query parameters. This can be useful if you want to handle anchor tags such as /#about
.

- 49,483
- 23
- 112
- 108
-
3What if your link is to an anchor like ``. How would you make that an active link? – Isaac Pak May 03 '20 at 20:03
-
How do you do it if you have class component? – user2570135 Jul 17 '20 at 02:37
-
1But this thing is not working if you route to nested links like www.example.com/blog/xyz . The link gets inactive in nested links – gurupal singh Jul 29 '20 at 03:00
-
16@gurupalsingh I think in this case you could use `router.pathname.startsWith("/about") ? "active" : ""` – Rotareti Jul 29 '20 at 09:06
-
This solution won't work if we have a parameter present in the page! – seem7teen Sep 18 '20 at 12:43
-
1@seem7teen You can use *split* to select the part before the parameters: `router.pathname.split("?")[0] == "/about" ? "active"` – Rotareti Sep 19 '20 at 12:26
-
Perfect. It worked for me...yayy thanks @Rotareti – Ibad Shaikh Feb 21 '21 at 13:03
-
oh my god. Really? Every library have built-in active class and `exact` flag. What's wrong with Next?! – Disorder Jun 19 '22 at 10:37
-
1Is there a way to match against dynamic paths like `[pid]`? Router.pathname returns `/[pid]`, and comparing with `/[pid]` as string is not good. – User Nov 16 '22 at 15:55
-
When I tried this, it caused a hydration error because the router.pathName will be different when statically rendered https://legacy.reactjs.org/docs/error-decoder.html/?invariant=418 – Zachary Rodriguez Jun 07 '23 at 00:06
First, you need to have a component called Link, with temporary attribute activeClassName
import { useRouter } from 'next/router'
import PropTypes from 'prop-types'
import Link from 'next/link'
import React, { Children } from 'react'
const ActiveLink = ({ children, activeClassName, ...props }) => {
const { asPath } = useRouter()
const child = Children.only(children)
const childClassName = child.props.className || ''
// pages/index.js will be matched via props.href
// pages/about.js will be matched via props.href
// pages/[slug].js will be matched via props.as
const className =
asPath === props.href || asPath === props.as
? `${childClassName} ${activeClassName}`.trim()
: childClassName
return (
<Link {...props}>
{React.cloneElement(child, {
className: className || null,
})}
</Link>
)
}
ActiveLink.propTypes = {
activeClassName: PropTypes.string.isRequired,
}
export default ActiveLink
Then have a navigation bar with created component Link and css selector :active
to differentiate between active and inactive link.
import ActiveLink from './ActiveLink'
const Nav = () => (
<nav>
<style jsx>{`
.nav-link {
text-decoration: none;
}
.active:after {
content: ' (current page)';
}
`}</style>
<ul className="nav">
<li>
<ActiveLink activeClassName="active" href="/">
<a className="nav-link">Home</a>
</ActiveLink>
</li>
<li>
<ActiveLink activeClassName="active" href="/about">
<a className="nav-link">About</a>
</ActiveLink>
</li>
<li>
<ActiveLink activeClassName="active" href="/[slug]" as="/dynamic-route">
<a className="nav-link">Dynamic Route</a>
</ActiveLink>
</li>
</ul>
</nav>
)
export default Nav
After that, you can implement the navigation bar to your page:
import Nav from '../components/Nav'
export default () => (
<div>
<Nav />
<p>Hello, I'm the home page</p>
</div>
)
The key of how does this work is located inside component Link, we compare the value of router.pathname
with attribute href
from the Link, if the value match the other then put specific className to make the link looks activated.
Reference: here

- 7,432
- 4
- 26
- 46
-
Where do I create the link file? In my components folder or in the root folder? Isn't it bad practice to have two files named "Link"? You have one from next/link and then a component named link. – larry burns Jul 15 '19 at 08:50
-
@larryburns your components folder, imho no as long as it is clear which Link are you pointing to, but you can also rename your Link Component to another name. It's up to you, you can re-define it in index file, or just rename the component so it is totally different from next/link component – Darryl RN Jul 16 '19 at 15:10
-
2But this thing is not working if you route to nested links like www.example.com/blog/xyz . The link gets inactive in nested links. – gurupal singh Jul 29 '20 at 02:59
-
See [my answer](https://stackoverflow.com/a/66950335/2252906) for a solution based on this code but taking care of nested links and url parameters – Felix Apr 05 '21 at 08:51
-
But it is not working for nested route. e.g. it is working for '/settings' but it is not working for '/settings/locations'. How can we enable same text as Active for multiple routes? – Deep Kakkar Oct 21 '21 at 11:30
If you're using Next 13 you can now do the following using the usePathname()
hook:
import { usePathname} from 'next/navigation';
export default function Example() {
const pathname = usePathname();
return(
<div>
<a
href="/welcome"
className={pathname == "/welcome" ?
"active" :
""
}
>
</div>
)
}

- 131
- 1
- 2
If you want to use an anchor Link try this version of @Rotareti 's code:
import Link from "next/link";
import { useRouter } from "next/router";
export const MyNav = () => {
const router = useRouter();
return (
<ul>
<li className={router.asPath == "/#about" ? "active" : ""}>
<Link href="#about">about</Link>
</li>
</ul>
);
};

- 2,957
- 4
- 17
- 37

- 279
- 4
- 5
Another minimal version which supports as
prop:
import Link from "next/link";
import {withRouter} from "next/router";
import {Children} from "react";
import React from "react";
export default withRouter(({router, children, as, href, ...rest}) => (
<Link {...rest} href={href} as={as}>
{React.cloneElement(Children.only(children), {
className: (router.asPath === href || router.asPath === as) ? `active` : null
})}
</Link>
));

- 4,454
- 4
- 38
- 58
-
3I like this answer, if you want to keep classes from children and just append, use: className: router.asPath === href || router.asPath === as ? `${children.props.className} active` : children.props.className – Goran Jakovljevic Jan 11 '19 at 10:10
-
1`router.asPath` was only working in dev(don't really know why), I replaced to `router.pathname === href || router.pathname === as` to work in production. – viery365 Mar 22 '19 at 17:19
Typescript version:
import React from 'react'
import Link, { LinkProps } from 'next/link'
import { useRouter } from 'next/router'
export interface NavLinkProps extends LinkProps {
children: React.ReactElement
}
export function NavLink({ children, href, ...props }: NavLinkProps) {
const router = useRouter()
return (
<Link href={href} {...props}>
{router.pathname === href ? React.cloneElement(children, { 'data-active': true }) : children}
</Link>
)
}
Note that I'm not cloning the child unless necessary.

- 62,658
- 20
- 139
- 163
Here is another version of ActiveLink with NextJS (see the result image below)
import { withRouter } from 'next/router';
import PropTypes from 'prop-types';
import React from 'react';
const ActiveLink = ({ router, href, isLeftSideBar = false, children }) => {
const isCurrentPath = router.pathname === href || router.asPath === href;
const handleClick = (e) => {
e.preventDefault();
router.push(href);
};
(function prefetchPages() {
if (typeof window !== 'undefined') router.prefetch(router.pathname);
})();
const theme =
settings.theme === THEMES.LIGHT && isLeftSideBar ? '#e65100' : '#ffeb3b';
const color = isCurrentPath ? theme : '';
return (
<a
href={href}
onClick={handleClick}
style={{
textDecoration: 'none',
margin: 16,
padding: 0,
fontWeight: isCurrentPath ? 'bold' : 'normal', // I left mine all bold
fontSize: 17,
color: isLeftSideBar ? '#e65100' : '#ffeb3b',
}}>
{children}
</a>
);
};
ActiveLink.propTypes = {
href: PropTypes.string.isRequired,
children: PropTypes.any,
};
export default withRouter(ActiveLink);
Call it anywhere
<ActiveLink href='/signup'> Sign Up </ActiveLink>
Result:

- 1,879
- 1
- 18
- 18
This is my solution. I tokenise the href
and the asPath
props and then loop through to match them.
You can choose an exact link (default)
<ActiveLink href='/events'>
<a href='/page'>Page</a>
</ActiveLink>
Or a fuzzy link (matches /events) with the fuzzy
prop
<ActiveLink fuzzy href='/events/id'>
<a href='/events/id'>Event</a>
</ActiveLink>
Here's the component
import React from 'react';
import NextLink from 'next/link';
import { useRouter } from 'next/router';
const ActiveLink = ({ fuzzy = false, href, children }) => {
const router = useRouter();
let className = children.props.className || '';
const hrefTokens = href.substr(1).split('/');
const pathTokens = router.asPath.substr(1).split('/');
let matched = false;
for (let i = 0; i < hrefTokens.length; i++) {
if (hrefTokens[i] === pathTokens[i]) {
matched = true;
break;
}
}
if ((!fuzzy && router.asPath === href) || (fuzzy && matched)) {
className = `${className} active`;
}
return (
<NextLink href={href}>
{React.cloneElement(children, { className })}
</NextLink>
);
};
export default ActiveLink;

- 24,431
- 10
- 56
- 61
Here is a solution that also works if URL-parameters are present and checks if a sub-page is active. Based on the answers by Darryl RN and Saman Mohamadi
It works as a drop-in replacement for the NextJS link component and adds the classes "active" and "active-sub" if the route or the route of a subpage is active.
Create a file called Link.js or whatever you like:
import { withRouter } from "next/router";
import Link from "next/link";
import React, { Children } from "react";
export default withRouter(({ router, children, as, href, activeClassName, activeSubClassName, ...rest }) => {
const child = Children.only(children);
const childClassName = child.props.className || "";
// remove URL parameters
const sanitizedPath = router.asPath.split("#")[0].split("?")[0];
// activeClassName and activeSubClassName are optional and default to "active" and "active-sub"
const activeClass = activeClassName || "active";
const activeSubClass = activeSubClassName || "active-sub";
// remove trailing slash if present
href = href && href !== "/" && href.endsWith("/") ? href.slice(0, -1) : href;
as = as && as !== "/" && as.endsWith("/") ? as.slice(0, -1) : as;
// check if the link or a sub-page is active and return the according class name
const activityClassName = sanitizedPath === href || sanitizedPath === as ? activeClass : sanitizedPath.startsWith(href + "/") || sanitizedPath.startsWith(as + "/") ? activeSubClass : "";
// combine the child class names with the activity class name
const className = `${childClassName} ${activityClassName}`.trim();
return (
<Link href={href} as={as} {...rest}>
{React.cloneElement(child, {
className: className || null,
})}
</Link>
);
});
import it in your files via
import Link from "./Link.js";
or with any name you like
import ActiveLink from "./Link.js";
and use it as you would use the NextJS "Link" component (next/link):
<Link href="/home">
<a className="link-classname">Home</a>
</Link>
it will default to the class names "active" and "active-sub", but you can set custom class names:
<Link href="/home" activeClassName="my-active-classname" activeSubClassName="another-classname">
<a className="link-classname">Home</a>
</Link>
If you don't need one of the active classes put a space in the string:
<Link href="/home" activeSubClassName=" ">
<a className="link-classname">Home</a>
</Link>

- 139
- 1
- 5
Just found this Tutorial from Vercel's team
If you're using Nextjs13, we can do it like this now! Doc
import { useSelectedLayoutSegment } from 'next/navigation';
export default function NavLink({href, children}) {
const segment = useSelectedLayoutSegment();
const active = href === `/${segment}`;
return (
<Link className={active ? "underline":""} href={href}>
{children}
</Link>
);
}

- 41
- 5
-
-
It's only works under "/app" folder. If you're using "/pages" folder use the pathname hook instead. – codajoao Aug 22 '23 at 19:36
In next 13 used this:
import Link from "next/link";
import { usePathname } from "next/navigation";
export default function Sidebar() {
const pathname = usePathname();
return (
<Link className={(pathname == "/app" ? "active" : "")}>
hello
</Link >
);
}

- 51
- 3
//NavItem Wrapper
import { useRouter } from 'next/router'
import React from 'react'
const ActiveNav = ({ path, children }) => {
const router = useRouter();
const className = router.asPath === `/${path}` ? "active" : '';
return (
<div className={className}>
{children}
</div>
)
}
export default ActiveNav
// in another file
import NavbarItem from 'path of ActiveNav component';
const { Header, Content, Footer } = Layout;
const LayoutComponent = (props) => {
return (
<>
<nav className="navigation">
<NavbarItem path="">
<div className="nav-items">
<Link href="/">
<a>Home</a>
</Link>
</div>
</NavbarItem>
<NavbarItem path="category/game">
<div className="nav-items">
<Link href="/category/game">
<a>Game</a>
</Link>
</div>
</NavbarItem>
</nav>
<>
)
}
export default LayoutComponent
add the style file and import it (Globally or in the Active Nav component)
.navigation > .active{
color:green;
font:bold;
// customize according to need
}

- 181
- 3
- 4
Nextjs 13.4+ Tailwind-css solution with example of Sidebar
You can use usePathname
from next/navigation
Example:
sidebar.tsx
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {
items: {
href: string;
title: string;
icon: any;
}[];
}
export function SidebarNav({ items }: SidebarNavProps) {
const pathname = usePathname();
return (
<nav className="flex flex-col p-4 h-full ">
{items.map((item) => (
<Link
key={item.href}
href={item.href}
className={`${
pathname === item.href
? "bg-green-500 hover:bg-green-500 text-white"
: "hover:bg-green-300 text-gray-800"
} flex items-center py-2 px-4 rounded-lg mb-2`}
>
<FontAwesomeIcon icon={item.icon} className="mr-2" />
<span>{item.title}</span>
</Link>
))}
</nav>
);
}
layout.tsx
import { SidebarNav } from "./components/sidebar";
import {
faBox,
faTags,
faList,
} from "@fortawesome/free-solid-svg-icons";
const sidebarNavItems = [
{
title: "Products",
href: "/products",
icon: faBox,
},
{
title: "Categories And Tags",
href: "/categories_tags",
icon: faTags,
},
{
title: "Listings",
href: "/listings",
icon: faList,
},
];
interface RootLayoutProps {
children: React.ReactNode;
}
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en">
<body className="h-screen">
<div className={cn("flex font-sans", inter.className, "h-full")}>
<aside className="bg-gray-100 h-full">
<div className="h-full py-4 px-2">
<SidebarNav items={sidebarNavItems} />
</div>
</aside>
<div className="flex-1 bg-white py-10 px-4">{children}</div>
</div>
</body>
</html>
);
}

- 14,953
- 4
- 49
- 88
I create a component in typescript
import { UrlObject } from "url";
interface ActiveLinkProps {
activeClassName?: string;
href: string | UrlObject;
}
// children is the <a>, prop is the "href"
const ActiveLink: React.FC<ActiveLinkProps> = ({ children, ...props }) => {
const router = useRouter();
// this will make sure i m passing only one child so i will access the its props easily
const child = Children.only(children) as React.ReactElement;
let className = child.props ? child.props.className : "";
if (router.asPath === props.href && props.activeClassName) {
className = `${className} ${props.activeClassName}`;
}
delete props.activeClassName;
return (
<Link href={props.href}>{React.cloneElement(child, { className })}</Link>
);
};
then use it like this
<ActiveLink activeClassName="active" href={href}>
<a className={`nav-link port-navbar-link ${className}`}>{title}</a>
</ActiveLink>

- 35,338
- 10
- 157
- 202
For those who are using Bootstrap this is the simplest solution
<Link href="/">
<a className={`nav-link ${router.pathname == "/" ? "active" : ""}`}>
Dashboard
</a>
</Link>

- 726
- 11
- 18
This worked for me
import { useRouter } from "next/router";
...
const router = useRouter();
const path = router.asPath.split("?")[0]; // (remove query string and use asPath since dynamic slug was rendering as "[slug]" using pathname)
...
const navigationList = (
<MenuList
>
{links.map((item) => {
const isActive = path == item.href;
return (
<MenuItem
key={item.id}
disabled={isActive}
sx={{
m: 0,
p: 0,
...(isActive && {
borderBottom: `1px solid ${theme.palette.primary.light}`,
backgroundColor: theme.palette.primary.dark,
}),
}}
>
<StyledLink href={item.href}>{item.label}</StyledLink>
</MenuItem>
);
})}
</MenuList>
);

- 4,757
- 1
- 32
- 23
This works with Next.js 13.2.4 & react-bootstrap 2.7.2:
const router = useRouter();
<Nav className="ms-auto">
<Nav.Link href="/" as={Link} className={router.pathname == '/' ? 'active' : ''}> Home </Nav.Link>
<Nav.Link href="/blog" as={Link} className={router.pathname == '/blog' ? 'active' : ''}> Blog </Nav.Link>
</Nav>

- 41
- 1
- 5
There is no built-in auto active class system in next.js but this package makes it very easy to have an active class for the active route.
Install package npm i active-link-nextjs
and use it like this.
import { useActiveRouter } from 'active-link-nextjs';
import Link from 'next/link';
const config = { activeClass: 'active' };
const MyComponent: React.FC = () => {
const { registerRoute } = useActiveRouter(config);
return (
<nav>
<Link {…registerRoute([''])}>Home</Link>
<Link {…registerRoute(['about'])}>About</Link>
<Link {…registerRoute(['blog'])}>Blog</Link>
</nav>
);
};
You can also override active class name for specific routes
<nav>
<Link {…registerRoute([''], )}>Home</Link>
<Link {…registerRoute(['about',
{ activeClass: 'special-active-class' }])}>
About
</Link>
<Link {…registerRoute(['blog'])}>Blog</Link>
</nav>
Read more Simplify your Next.js app’s active links with useActiveRouter and Link

- 683
- 1
- 6
- 23
Just put an a tag in it...
<Link href={href}>
<a className='text-red-400 active:text-red-800'>{children}</a>
</Link>

- 37
- 4
-
2OP didn't mention Tailwind or any CSS framework, and regarding `active`, said _"give the active link a class when its route is active"_. That's not what the CSS [`active`](https://developer.mozilla.org/en-US/docs/Web/CSS/:active) pseudo-class does. – ChrisCrossCrash Nov 17 '21 at 08:43