Reputation: 363
I have a question about styling an anchor component when it is on the active page.
Here is my code:
import Link from 'next/link';
import styled from 'styled-components';
const NavStyle = styled.nav`
display: flex;
justify-content: space-between;
.nav-link a {
text-decoration: none;
color: white;
padding: 10px;
background-color: #FFCF00;
}
`;
export default function Nav() {
return (
<NavStyle>
<div className="nav-link">
<Link href="/" passHref>
<a>HOME</a>
</Link>
<Link href="/pricing">
<a>PRICING</a>
</Link>
<Link href="/terms">
<a>TERMS</a>
</Link>
<Link href="/login">
<a>LOGIN</a>
</Link>
</div>
<Link href="/">
<a>LOGO</a>
</Link>
</NavStyle>
)
}
What I want is, when the I click on the link and move to another page, the active link (that's matched with the URL) would have a green background. I have tried this, but it doesn't make any change:
const NavStyle = styled.nav`
display: flex;
justify-content: space-between;
.nav-link a {
text-decoration: none;
color: white;
padding: 10px;
background-color: #FFCF00;
&[aria-current] {
background-color: green;
}
}
`;
Upvotes: 12
Views: 33769
Reputation: 45052
This is how I am doing it in my project with Material Ui
export default function MainAppBar(props: Props) {
const theme = useTheme();
const {navItems} = props
const pathname = usePathname()
.... rest of code
return (
{navItems && <Box sx={{ display: { xs: "none", sm: "block" } }}>
{navItems.map((item, index) => (
<Link
key={index}
href={item["href"]}
passHref
>
<Button
sx={{ color: pathname === item["href"] ? '#ff7' : 'inherit' }}>
{item["text"]}
</Button>
</Link>
))}
</Box>
}
....
);
}
then I pass links as prop
export const LINKS: { text: string, href: string, icon: JSX.Element }[] = [
{ text: "Home", href: "/", icon: <Home /> },
{ text: "Work", href: "/work", icon: <Star /> },
{ text: "Blogs", href: "/blog", icon: <Checklist /> },
{ text: "Typography", href: "/typography", icon: <Checklist /> },
];
Usage:
<MainAppBar navItems={LINKS} />
Result:
Upvotes: 0
Reputation: 7
In case some one is using MaterialUI is easy to use a wrapper Box
router comes from const router = useRouter();
that is part of next/router
<Box
sx={{
'& a':{
color: router.pathname === '/' ? '#757de8' : 'rgba(0, 0, 0, 0.87)'
}
}}>
<Link href={'/'}> HOME </Link>
</Box>
Upvotes: 1
Reputation: 13
The best answer to this question that I have found is at https://amanexplains.com/using-aria-current-for-nav-links/
Note that the first answer to this question says to use pathname, but the link I provided describes why that won't work in some cases (slugged paths, for instance). Instead, use asPath.
Note also that this currently (NextJS 13) only works for client-side components as far as I can tell.
Upvotes: 0
Reputation: 23141
Next.js won't add aria-current
to your active link; however, you can create a custom Link
component that checks if the current pathname
is the same as the href
prop.
import React from "react";
import Link from "next/link";
import { useRouter } from "next/router";
const NavLink = ({ children, href }) => {
const child = React.Children.only(children);
const router = useRouter();
return (
<Link href={href}>
{React.cloneElement(child, {
"aria-current": router.pathname === href ? "page" : null
})}
</Link>
);
};
export default NavLink;
Then, you can use this component instead of the default Link
whenever you want to add aria-current
to the active link:
const NavStyle = styled.nav`
display: flex;
justify-content: space-between;
a {
background-color: #353637;
color: #fff;
padding: 1rem;
text-decoration: none;
&[aria-current] {
background-color: #faf9f4;
color: #353637;
}
}
`;
export default function Nav() {
return (
<NavStyle>
<div className="nav-link">
<NavLink href="/">
<a>HOME</a>
</NavLink>
<NavLink href="/pricing">
<a>PRICING</a>
</NavLink>
<NavLink href="/terms">
<a>TERMS</a>
</NavLink>
<NavLink href="/login">
<a>LOGIN</a>
</NavLink>
</div>
<Link href="/">
<a>LOGO</a>
</Link>
</NavStyle>
);
}
Upvotes: 9