# How to Implement an Active NavLink with React Router: A Complete Guide

> Learn to implement an active NavLink with React Router. Use the `isActive` prop to dynamically style your current page link for a better user experience. Complete React guide.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-20

---

**Use the `NavLink` component from `react-router-dom` and provide a function to the `className` or `style` prop that receives `{ isActive }` to dynamically apply styling when the link matches the current route.**

Implementing an active NavLink with React Router is essential for creating intuitive navigation interfaces that visually indicate the user's current location. The `react-router-dom` package provides a specialized `NavLink` component that automatically handles route matching and active state detection, eliminating the need for manual pathname comparisons in most cases. Unlike the standard `Link` component, `NavLink` is designed specifically for navigation menus where visual feedback improves user experience.

## Understanding the NavLink Component

The `NavLink` component extends the standard `Link` component with built-in active state detection. According to the `react-router-dom` source code (located in [`packages/react-router-dom/NavLink.tsx`](https://github.com/facebook/react/blob/main/packages/react-router-dom/NavLink.tsx)), the component works by comparing the resolved URL of the link to the browser's current pathname. When they match, `NavLink` automatically injects either a CSS class (defaulting to `"active"`), a custom class, or a style object that you provide.

## Core Props for Active Navigation

### The className Function Prop

The `className` prop accepts either a static string or a function that receives navigation data and returns a string. This function receives an object containing `isActive` and `isPending` boolean flags, allowing you to construct dynamic class names based on the current route state.

```tsx
import { NavLink } from "react-router-dom";

<NavLink
  to="/dashboard"
  className={({ isActive }) => (isActive ? "nav-link active" : "nav-link")}
>
  Dashboard
</NavLink>

```

### The style Function Prop

Similar to `className`, the `style` prop can accept a function that returns a `CSSProperties` object. This approach is ideal for inline styling or when using CSS-in-JS solutions where you need to programmatically adjust styles based on the active state.

```tsx
import { NavLink } from "react-router-dom";

<NavLink
  to="/notifications"
  style={({ isActive }) => ({
    color: isActive ? "#ff6600" : "#333",
    fontWeight: isActive ? "600" : "400",
  })}
>
  Notifications
</NavLink>

```

### Exact Matching with the end Prop

By default, `NavLink` considers a link active when the current pathname starts with the link's path. For root routes or when you need exact matching, use the `end` prop. When `end` is `true`, the link is only active when the pathname exactly matches the `to` prop value.

```tsx
<NavLink to="/" end>
  Home (active only on exact "/")
</NavLink>

```

## Implementation Examples

### Basic Active Class Implementation

For simple navigation menus, you can rely on the default `"active"` class that `NavLink` automatically applies. Define your CSS to style the active state, and let the component handle the rest.

```tsx
import { NavLink } from "react-router-dom";

function MainMenu() {
  return (
    <nav>
      <NavLink to="/" end>Home</NavLink>
      <NavLink to="/about">About</NavLink>
      <NavLink to="/contact">Contact</NavLink>
    </nav>
  );
}

```

```css
.nav-link { padding: 8px; color: #555; }
.nav-link.active { font-weight: bold; color: #000; }

```

### Dynamic Styling with CSS Modules

When using CSS Modules or scoped styling, use the function form of `className` to return the appropriate class based on `isActive`.

```tsx
import { NavLink } from "react-router-dom";
import styles from "./Sidebar.module.css";

function Sidebar() {
  return (
    <aside>
      <NavLink
        to="/settings"
        className={({ isActive }) =>
          isActive ? styles.selected : styles.item
        }
      >
        Settings
      </NavLink>
    </aside>
  );
}

```

### Custom Active Logic with useLocation

For complex matching requirements—such as considering query strings, hash fragments, or custom patterns—you can compute the active state manually using the `useLocation` hook and pass the result to `NavLink` or a styled wrapper.

```tsx
import { NavLink, useLocation } from "react-router-dom";

function MyNavLink({ to, children }) {
  const location = useLocation();
  const isActive = location.pathname === to; // simple exact match

  return (
    <NavLink
      to={to}
      className={isActive ? "active-link" : undefined}
    >
      {children}
    </NavLink>
  );
}

```

## Accessibility Considerations

`NavLink` automatically manages the `aria-current` attribute for active links, setting it to `"page"` by default when the link is active. This signals to screen readers that the link represents the current page, which is essential for users navigating with assistive technologies. You can customize this behavior using the `ariaCurrent` prop if your design requires a different value, though `"page"` is the standard for navigation menus.

## Summary

- **Use `NavLink`** instead of `Link` when you need visual indication of the current route in navigation menus.
- **Leverage function props** for `className` and `style` to dynamically apply styling based on the `isActive` boolean.
- **Apply the `end` prop** for root routes or when you need exact matching rather than prefix matching.
- **Rely on built-in accessibility** features like automatic `aria-current="page"` attributes for screen reader support.
- **Reference the source** in `react-router-dom` (specifically the `NavLink` component implementation in [`packages/react-router-dom/NavLink.tsx`](https://github.com/facebook/react/blob/main/packages/react-router-dom/NavLink.tsx)) for advanced customization patterns.

## Frequently Asked Questions

### What is the difference between Link and NavLink in React Router?

`Link` is the fundamental component for creating navigation anchors in React Router, rendering a standard accessible anchor tag that updates the URL when clicked. `NavLink` extends `Link` with active state detection, automatically applying styling classes or inline styles when the link's route matches the current location, making it ideal for navigation menus where you need to highlight the current page.

### How do I make a NavLink active only on exact match?

Use the `end` prop on your `NavLink` component. By default, `NavLink` uses partial matching, meaning `/dashboard` would be considered active for both `/dashboard` and `/dashboard/settings`. When you add `end={true}`, the link only receives the active state when the current pathname exactly matches the `to` prop value, which is particularly important for root home routes (`to="/"`).

### Can I use NavLink with CSS Modules or Tailwind CSS?

Yes, `NavLink` works seamlessly with CSS Modules, Tailwind CSS, and any CSS-in-JS solution. Use the function form of the `className` prop to return the appropriate class names based on the `isActive` state. For Tailwind, you might return conditional strings like `isActive ? "bg-blue-500 text-white" : "text-gray-600"`, while for CSS Modules, you would return `isActive ? styles.active : styles.link`.

### Why is my NavLink not showing as active?

The most common cause is a mismatch between the `to` prop value and the current pathname, particularly with trailing slashes or partial matching behavior. Ensure your route paths match exactly, or use the `end` prop if you need exact matching. Also verify that your CSS selectors are correctly targeting the `.active` class (or your custom class) and that no other styles are overriding them. If using the function form of `className`, debug by logging the `isActive` value to ensure it matches your expectations.