I am using NextJS and Tailwind css to desig a top navigation bar. I want the text color to change for active link. Below is my code:
const Header = () => {
return(
<header>
<nav className="sd:max-w-6xl mx-auto">
<ul className="flex py-2">
<li className="mr-auto ml-4">
<Link href="/"><a><Image width={80} height={80} src="/images/brand-logo.png" alt="ECT Logo"/></a></Link>
</li>
<li className="mr-4 my-auto hover:text-indigo-600 font-normal font-serif text-brand-darkblue text-xl active:text-indigo-600">
<Link href="/"><a>Home</a></Link>
</li>
<li className="mr-4 my-auto hover:text-indigo-600 font-normal font-serif text-brand-darkblue text-xl active:text-indigo-600">
<Link href="/user/signup"><a>Join</a></Link>
</li>
<li className="mr-4 my-auto hover:text-indigo-600 font-normal font-serif text-brand-darkblue text-xl active:text-indigo-600">
<Link href="/user/login"><a>Login</a></Link>
</li>
</ul>
</nav>
</header>
)
}
I have also added the following in my tailwind.config.css:
module.exports = {
#
variants: {
extend: {
textColor: ['active'],
},
}
Despite that the Text color doesn't change for active link.
Can you please guide what I am doing wrong.
It seems there's a mix-up between two concepts:
active state in Tailwind CSS, which refers to the state of an element while it's being pressed (https://tailwindcss.com/docs/hover-focus-and-other-states#active).nav item's href.You cannot achieve 2 with 1, they are different things.
To distinguish and indicate the current page (concept 2), you need to compare the current path with the <Link> element's path and apply conditional Tailwind classes accordingly.
For Next.js Pages Router:
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>
)
}
Source: https://dev.to/yuridevat/how-to-add-styling-to-an-active-link-in-nextjs-593e
For Next.js App Router (Update March 2024):
'use client';
import { usePathname } from 'next/navigation';
export const Header = () => {
const pathname = usePathname();
return (
<header>
<Link href="/">
<a className={pathname === "/" ? "active" : ""}>
Home
</a>
</Link>
</header>
);
};
I like to do something like this:
import { usePathname } from "next/navigation";
const NAV_ITEMS = [
{ href: "/", label: "Home" },
{ href: "/about", label: "About" },
];
export const Nav = () => {
const pathname = usePathname();
return (
<nav>
{NAV_ITEMS.map(({ href, label }) => {
const isActive = pathname === href;
return (
<Link
key={href}
href={href}
className={`${isActive ? "text-blue-500" : "text-black"} text-sm`}
>
{label}
</Link>
);
})}
</nav>
);
};
With a helper library like classnames, this would become:
<Link
key={href}
href={href}
className={classnames("text-sm", {
"text-blue-500": isActive,
"text-black": !isActive,
})}
>
{label}
</Link>;
Applying this to your code, you could adjust the className like so:
<Link href="/user/signup">
<a className={`mr-4 my-auto hover:text-indigo-600 font-normal font-serif text-xl ${router.pathname == "/user/signup" ? "text-indigo-600" : "text-brand-darkblue"}`}>
Home
</a>
</Link>
When using NavLink it's add class active to link but not active state in tailwindcss
The simplest way is to use custom variant like this
<NavLink to={``} className={'[&.active]:text-indigo-500}>
</NavLink>
This way is both pure css and takes advantage of the power of tailwindcss. Furthermore, avoid using state when it is not necessary to avoid the rendering problem
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With