🧭 Highlighting Active Links in Next.js 15 using usePathname & Client Components

When building a website with multiple pages, it’s important to show which page the user is currently on. For example, if the user is on the Community page, the nav link for that page should look "active".

Let’s learn how to achieve this in Next.js using:

✅ usePathname() hook
✅ use client directive
✅ Component splitting for performance


🧠 Understanding the usePathname() Hook

The usePathname() hook is provided by Next.js and allows you to get the current route path like:

/community
/meals

It is imported from:

import { usePathname } from 'next/navigation';

But here’s the catch:

usePathname() only works in Client Components.

This means, if you use it inside a Server Component (which is default in Next.js), you’ll get an error.


🧩 So What Are Client Components?

In Next.js, components are Server by default.

Client Components:

  • Can access browser-only features like usePathname, useEffect, localStorage, etc.

  • Must start with the "use client" directive at the top of the file.


Let's break this down into a simple and optimized setup:

1. 🛠 Create a Client-Side Component (NavLink.js)

This small component will:

  • Accept href and children as props

  • Check if the current path matches the href

  • Add an active CSS class if it matches

// components/NavLink.js
'use client';

import Link from 'next/link';
import { usePathname } from 'next/navigation';
import classes from './nav-link.module.css';

export default function NavLink({ href, children }) {
  const path = usePathname();
  const isActive = href === '/' ? path === href : path.startsWith(href);

  return (
    <Link
      href={href}
      className={`${classes.link} ${isActive ? classes.active : ''}`}
    >
      {children}
    </Link>
  );
}
/* nav-link.module.css */
.link {
  text-decoration: none;
  color: #555;
  padding: 0.5rem 1rem;
  transition: all 0.3s;
}

.active {
  font-weight: bold;
  color: #ff6600;
  border-bottom: 2px solid #ff6600;
}
// components/MainHeader.js
import NavLink from './NavLink';

export default function MainHeader() {
  return (
    <nav>
      <NavLink href="/meals">Browse Meals</NavLink>
      <NavLink href="/community">Foodies Community</NavLink>
    </nav>
  );
}

You can now avoid using "use client" in your large Server Component, keeping it optimized!


✅ Why This is Best Practice?

TechniqueWhy it matters
usePathname()Reads current URL path in browser
Client Component onlyBecause usePathname is browser-only
Component SplittingKeeps server-rendered code lightweight
Active Link HighlightImproves user experience

💡 Summary

  • Use usePathname() inside a Client Component.

  • Wrap that logic in a small reusable <NavLink />.

  • Keep large components like <MainHeader /> as Server Components for better performance.

  • Add styles to show active links with simple CSS.

0
Subscribe to my newsletter

Read articles from Muhammad Sufiyan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Muhammad Sufiyan
Muhammad Sufiyan

As a former 3D Animator with more than 12 years of experience, I have always been fascinated by the intersection of technology and creativity. That's why I recently shifted my career towards MERN stack development and software engineering, where I have been serving since 2021. With my background in 3D animation, I bring a unique perspective to software development, combining creativity and technical expertise to build innovative and visually engaging applications. I have a passion for learning and staying up-to-date with the latest technologies and best practices, and I enjoy collaborating with cross-functional teams to solve complex problems and create seamless user experiences. In my current role as a MERN stack developer, I have been responsible for developing and implementing web applications using MongoDB, Express, React, and Node.js. I have also gained experience in Agile development methodologies, version control with Git, and cloud-based deployment using platforms like Heroku and AWS. I am committed to delivering high-quality work that meets the needs of both clients and end-users, and I am always seeking new challenges and opportunities to grow both personally and professionally.