React Navigation with NavLink

In the last lesson, React Navigation with Link, you added links that change pages with no reload. Now let’s use NavLink to highlight which page the user is currently on.

Here’s the pain. A plain Link always looks the same, whether you’re on that page or not.

  • In a nav menu, users expect the current page to stand out, like bold or a different color.
  • A plain Link can’t tell whether it points to the page you’re already on.
  • You’d have to manually check the URL for every link and apply a style. That’s tedious.
  • You want the link to figure out “am I the active page?” on its own.

So NavLink solves exactly this. It’s like Link, but it automatically knows when it’s the active page and lets you style that state.

NavLink works just like Link, with the same to prop. The difference is it can change its style based on whether it’s active.

import { NavLink } from "react-router-dom";
function Navbar() {
return (
<nav>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/contact">Contact</NavLink>
</nav>
);
}

So far this looks the same as Link, and that’s the point.

  • We import NavLink instead of Link.
  • It uses the same to prop and navigates the same way, with no reload.
  • The extra power is that it can tell when its to matches the current URL.

So everything you know about Link carries over. NavLink just adds the “am I active?” ability.

Here’s the real feature. NavLink can take a function for className or style, and that function receives an isActive value telling you if this is the current page.

import { NavLink } from "react-router-dom";
function Navbar() {
return (
<nav>
<NavLink
to="/about"
className={({ isActive }) => (isActive ? "active" : "")}
>
About
</NavLink>
</nav>
);
}

Walk through how the active styling works.

  • className is given a function, not a plain string.
  • That function receives an object with isActive, which is true when this link is the current page.
  • So when you’re on /about, this link gets the "active" class; otherwise it gets "".
  • You then style the .active class in your CSS, like making it bold or colored.

isActive does the hard work

You don’t check the URL yourself. NavLink compares its to against the current URL and hands you isActive. You just decide what to do when it’s true.

🖌️ Styling with the style prop instead

If you’d rather set styles inline than use a CSS class, the style prop works the same way, with the same isActive.

<NavLink
to="/about"
style={({ isActive }) => ({
fontWeight: isActive ? "bold" : "normal",
color: isActive ? "blue" : "black",
})}
>
About
</NavLink>

Same idea, just inline.

  • style also takes a function that receives isActive.
  • It returns a style object, with different values when the link is active.
  • Here the active link is bold and blue, and the others are normal and black.

So whether you use className or style, the pattern is identical: a function that reads isActive and returns the right styling.

⚠️ Common Mistakes

A common mistake is using a plain string for className and expecting active styling to just happen.

// ❌ a plain string - this class is always applied, active or not
<NavLink to="/about" className="active">About</NavLink>
// ✅ a function that checks isActive
<NavLink to="/about" className={({ isActive }) => (isActive ? "active" : "")}>
About
</NavLink>

Keep these in mind.

  • Don’t pass a plain string and expect highlighting. Use a function that reads isActive.
  • Don’t use NavLink for every link. It’s for navigation menus where active state matters. A plain Link is fine elsewhere.
  • Don’t forget to actually style the active class or styles in your CSS, or nothing visible changes.

✅ Best Practices

A few habits for NavLink.

  • Use NavLink for navigation menus where you want to highlight the current page.
  • Use a className or style function that reads isActive to apply the active look.
  • Use plain Link for one-off links in content, where active highlighting isn’t needed.
  • Keep the active style clear but not distracting, like a bold weight or an underline.

Same speed as Link

NavLink navigates exactly like Link, with no page reload. The only added feature is knowing when it’s active. So in a menu, reach for NavLink; everywhere else, Link is enough.

🧩 What You’ve Learned

  • NavLink is like Link but it knows when its page is the active one
  • ✅ It uses the same to prop and navigates with no reload
  • ✅ Pass a function to className or style that receives isActive
  • isActive is true when the link’s to matches the current URL, so you can highlight it
  • ✅ Style the active state in CSS (a class) or inline (a style object)
  • ✅ Use NavLink for nav menus; a plain Link is fine for other links

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does NavLink add compared to Link?

    Why: NavLink navigates just like Link, but it can tell when its to matches the current URL, which lets you style the active page in a menu.

  2. 2

    How do you apply an active style with NavLink?

    Why: NavLink gives className and style a function with an isActive value. You return different styling when isActive is true.

  3. 3

    What is isActive?

    Why: isActive is true when this NavLink points to the page you're currently on, so you can decide how to style the active link.

  4. 4

    When should you use NavLink instead of Link?

    Why: Use NavLink in nav menus where the active page should stand out. For ordinary one-off links, a plain Link is simpler and enough.

🚀 What’s Next?

Now your menus can highlight the active page on their own. So far navigation happens when the user clicks. But sometimes your code needs to move to a page itself, like after a successful login. Next you’ll learn the useNavigate hook.

React useNavigate Hook

Share & Connect