DEV Community

Cover image for How to add styling to an active link in NextJS

How to add styling to an active link in NextJS

For my latest project, I wanted to change the background color of the active navigation link in the <Header> when being clicked. When working with <Link> in React (using React-Router) in the past, I had the possibility to add an activeClassName to the <Link> to change the style when being active. But this built-in <Link> is not available in NextJS. Let me show you the differences and how you can add an active class to a <Link> in NextJS.


Table Of Contents

  1. React's activeClassName
  2. Create an active link in NextJS

React's activeClassName

This special version of the <Link> tag is called <NavLink> and adds styling attributes to the rendered element when it matches the current URL. There are two different ways to add styling.

activeClassName: string

The class is given to the element when it is active by writing:

<NavLink to="/about" activeClassName="active">
  About
</NavLink>
Enter fullscreen mode Exit fullscreen mode

activeStyle: object

The styles is applied to the element when it is active by writing:

important: use double curly brackets instead of single ones in activeStyle*

<NavLink to="/about" activeStyle={fontWeight: "bold"}>
  About
</NavLink>
Enter fullscreen mode Exit fullscreen mode

Create an active link in NextJS

The default <Link> component from NextJS doesn't allow to distinguish between active and non-active links. In NextJS, you can use the built-in router to detect an active link.

I am using the useRouter hook inside my "Header function component" and created a ternary operator to check if the <Link> to style matches the currently displayed route.

Here's the code:

import Link from 'next/link';
import { useRouter } from 'next/router';

export const Header = () => {
  const router = useRouter();

  return (
    <header>
      <Link href="/">
        <a className={router.pathname == "/" ? "active" : ""}>
           Home
        </a>
      </Link>
    </header>
  )
}
Enter fullscreen mode Exit fullscreen mode

For more information on next/router check out the documentation.

*) When I try to save it with double curly brackets an error message appears.


Thank you

Thanks for your reading and time. I really appreciate it!

Discussion (16)

Collapse
chiangs profile image
Stephen E. Chiang • Edited on

Just a reminder to those who are reading this, that if you insert <a/> wrapped inside a custom component inside <Link/> that you should include passHref if the <a/> wraps anything other than a string, otherwise your site may take a hit on SEO.

Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

Wow, thanks for this information, didn't know about that.

Collapse
ebartan profile image
Eray Bartan

julia it's fantactic tricks
how to change actve style in nextjs?
you save my day. tahnks a lot.

Collapse
jsingle345 profile image
Joshua Singleton

This helped me out tremendously. Helped me out so much that I created an account just to say thank you!

Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

Thank you so much for your kind words :) Glad it helped!

Collapse
w3bdesign profile image
w3bdesign

I would recommend extracting this to a separate function. Then you can do the following:

const activeLink = (url: string, pathname: string) => pathname === url ? "navbar-link-active" : "";
Enter fullscreen mode Exit fullscreen mode

Then you can do something like this in your links (if you use string literals):

${activeLink(link.url, router.pathname)
Enter fullscreen mode Exit fullscreen mode
Collapse
amroyasser profile image
Amr Yasser

I'm a backend developer who has no knowledge in next.js. However, I needed to change something in the front-end. It took me much time trying to figure it out myself. Once I found this post, I could do it. Thanks a lot!

Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

Glad that it helped :)

Collapse
itwasmattgregg profile image
Matt Gregg

Just a note, it would be sweet if your code samples were gist embeds or code blocks so people could copy/paste from them. The pictures look nice but it makes it harder to copy.

Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

Hey Matt. Thank you so much for your suggestion. I changed the img to code blocks and will continue doing that :)

Collapse
amirreza_dev profile image
Amirreza Kadkhodazadeh

thank you it was very useful

Collapse
peritpatrio profile image
Petri Partio

There’s a typo in the code.

const router = userRouter();
Enter fullscreen mode Exit fullscreen mode

should be:

const router = useRouter();
Enter fullscreen mode Exit fullscreen mode
Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

Thank you, I fixed it :)

Collapse
victorchweya profile image
Victor Chweya

You are a life saver, thanks for this

Collapse
akash_stha01 profile image
akash shrestha • Edited on

Great but I am using dynamic pathname and it doesn't work for me.
router.asPath may help

Collapse
yuridevat profile image
π•π•¦π•π•šπ•’ πŸ‘©πŸ»β€πŸ’» Author

That's too bad. I hope you find a solution for your case soon.