Site icon FSIBLOG

How to Get the Current Pathname in the App Directory of Next.js?

How to Get the Current Pathname in the App Directory of Next.js?

How to Get the Current Pathname in the App Directory of Next.js?

When I first switched to the App Router in Next.js 13, I ran into something that left me scratching my head. I was trying to highlight the active link in my navbar something super common. In previous versions of Next.js, I used useRouter() from next/router, which gave me the handy pathname property. But when I updated my code using next/navigation (as recommended for the App Directory), I realized:

Here’s how I discovered the issue, how I fixed it, and how I made the solution more reusable and powerful. Let’s break it down.

Original Code with Error

Here’s the initial code I wrote, expecting pathname to be available:

Link from "next/link";
import { useRouter } from 'next/navigation'; // Correct for App Router

const StyledNavLink: React.FC<NavLinkProps> = ({ to, children }) => {
const router = useRouter(); // 🚨 'pathname' is not available here

return (
<Link href={to} className={getNavLinkClass({ isActive: router.pathname === to })}>
{children}
</Link>
);
};

Error:

'pathname' does not exist on type 'AppRouterInstance'

Why This Happened:

In the new App Router, useRouter() gives us navigation methods (like push() or replace()), but it no longer gives access to the current pathname. Instead, we need to use a different hook: usePathname().

Corrected Code Using usePathname()

Once I discovered the correct hook, I updated the code like this:

Link from "next/link";
import { usePathname } from 'next/navigation';

interface NavLinkProps {
to: string;
children: React.ReactNode;
}

const StyledNavLink: React.FC<NavLinkProps> = ({ to, children }) => {
const pathname = usePathname(); // This gives us the current path

const isActive = pathname === to;

return (
<Link
href={to}
className={isActive ? "text-blue-500 font-bold" : "text-gray-500"}
>
{children}
</Link>
);
};

export default StyledNavLink;

Explanation:

Bonus Practice Partial Match & Custom Classes

I wanted a bit more control. What if I’m on a nested route like /blog/my-post and still want the /blog link to be highlighted?

Here’s the upgraded version of the component that:

Link from "next/link";
import { usePathname } from 'next/navigation';
import clsx from 'clsx'; // Optional utility for clean class handling

interface NavLinkProps {
to: string;
children: React.ReactNode;
exact?: boolean;
activeClass?: string;
inactiveClass?: string;
}

const StyledNavLink: React.FC<NavLinkProps> = ({
to,
children,
exact = false,
activeClass = "text-blue-600 font-bold",
inactiveClass = "text-gray-600",
}) => {
const pathname = usePathname();

const isActive = exact ? pathname === to : pathname.startsWith(to);

return (
<Link href={to} className={clsx(isActive ? activeClass : inactiveClass)}>
{children}
</Link>
);
};

export default StyledNavLink;

What I Added:

How I Used It in My App

<StyledNavLink to="/" exact>Home</StyledNavLink>
<StyledNavLink to="/about">About</StyledNavLink>
<StyledNavLink to="/blog">Blog</StyledNavLink>

This setup made my navbar dynamic and responsive to the current route, just like I wanted—clean, elegant, and App Router–friendly.

Final Thoughts

Switching to the App Directory in Next.js 13 definitely comes with a bit of a learning curve. But once I understood that useRouter() was now navigation-only and usePathname() was my new best friend, things clicked.

Exit mobile version