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.
You might be confusing two things:
active prefix in Tailwind CSS is applied, whenever an element is currently pressed. (e.g. while you press on a link or button) (https://tailwindcss.com/docs/hover-focus-and-other-states#active)nav item`s hrefYou cannot achieve 2 with 1, they are different things.
To achieve 2 in next.js, you would need to get the current path, compare it to the <Link> element's path and if they're equal, add conditional tailwind classes that show that you're currently on the respective page.
Here is a code example how you can achieve 2:
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
In your case, you could do something like this:
<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>
You need to use NavLink instead of Link it will match the current URL here is an example I've used :
<NavLink to={`/${link.name}`} className={ ({isActive})=> (" capitalize my-2 flex flex-col ") + (isActive?ActiveLink:NormalLink) }>
{link.name}
</NavLink>
Using NextJs and Tailwind using toggle dark/light mode, this is how I solved it
//ActiveLink.js
import { useRouter } from 'next/router';
import Link from 'next/link';
import PropTypes from 'prop-types';
import { useTheme } from 'next-themes';
const ActiveLink = ({ href, children, ...rest }) => {
const router = useRouter();
const { theme, systemTheme } = useTheme();
const useLoaded = () => {
const [loaded, setLoaded] = useState(false);
useEffect(() => setLoaded(true), []);
return loaded;
};
const mounted = useLoaded();
const isActive = router.asPath === href;
const currentTheme =
mounted && theme !== undefined && theme === 'system' ? systemTheme : theme;
const activeLinkBgColor =
currentTheme === 'dark'
? 'bg-gray-700 text-white'
: 'bg-blue-600 text-white';
const themeBgHover =
currentTheme === 'dark'
? 'hover:bg-gray-700 hover:text-white'
: 'hover:bg-blue-600 hover:text-white ';
const activeLinkAndNotActiveColor = isActive
? activeLinkBgColor
: `text-gray-300 ${themeBgHover}`;
const className = `${activeLinkAndNotActiveColor} px-3 py-2 rounded-md text-sm font-medium`;
return (
<Link href={href} passHref {...rest}>
<a className={className} aria-current={isActive ? 'page' : undefined}>
{children}
</a>
</Link>
);
};
ActiveLink.propTypes = {
href: PropTypes.string.isRequired,
};
export default ActiveLink;
// How to use it
<ActiveLink href='/about'> About </ActiveLink>
Good luck.