Active Navbar means that when the user is on the about
page, the about
link should be highlighted in the navbar. and when the user is on a different page and its link is available in the navbar, that should be highlighted.
If you don't get it then the following is the demo of what I am talking about and how it's gonna turn out-
Preview
As you can see in the above demo when the user clicks any of the navbar sections the page route changes and the active page name is highlighted on the navbar. That's what are we going to build.
Creating Layout
If you don't have a Layout then you need to create a layout first. and Add that Layout
component to the _app.js
.
// components/Layout.jsx
import Navbar from "./Navbar";
export default function Layout({ children }) {
return (
<>
<Navbar />
{children}
{/* Footer */}
{/* You can add more things here */}
</>
);
}
In the above code, you can see that we are importing Navbar
and then we are rendering the Navbar
inside the Layout
.
Now, after creating Layout we need to wrap our whole app with Layout. It should look something like this-
// pages/_app.js
import "../styles/global.css";
import Layout from "./../components/Layout";
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
Creating Navbar
Create a file name Navbar.jsx
in the components folder. and first, import the Link
and useRouter
as we need those to check the current page route.
// components/Navbar.jsx
import { useRouter } from "next/router";
import Link from "next/link";
Then we need to define all the routes which we have and want to show on the navbar.
// components/Navbar.jsx
const navigationRoutes = ["home", "about", "pricing", "contact"];
export default function Navbar() {
const router = useRouter();
return (
<nav className="nav_container">
{navigationRoutes.map((singleRoute) => {
return (
<NavigationLink
key={singleRoute}
href={`/${singleRoute}`}
text={singleRoute}
router={router}
/>
);
})}
</nav>
);
}
In the above code, we are defining the router
and then we are creating a nav
container. After that, I am mapping navigationRoutes
and for each route, we are returning NavigationLink
which we will create in a minute.
*Props: *
-
href
: route link -
text
: text that will be displayed on the navigation bar -
router
: verify the current route
// components/Navbar.jsx
function NavigationLink({ href, text, router }) {
const isActive = router.asPath === (href === "/home" ? "/" : href);
return (
<Link href={href === "/home" ? "/" : href} passHref>
<a
href={href === "/home" ? "/" : href}
className={`${isActive && "nav_item_active"} nav_item`}>
{text}
</a>
</Link>
);
}
Full Navigation Code-
import { useRouter } from "next/router";
import Link from "next/link";
const navigationRoutes = ["home", "about", "pricing", "contact"];
export default function Navbar() {
const router = useRouter();
return (
<nav className="nav_container">
{navigationRoutes.map((singleRoute) => {
return (
<NavigationLink
key={singleRoute}
href={`/${singleRoute}`}
text={singleRoute}
router={router}
/>
);
})}
</nav>
);
}
function NavigationLink({ href, text, router }) {
const isActive = router.asPath === (href === "/home" ? "/" : href);
return (
<Link href={href === "/home" ? "/" : href} passHref>
<a
href={href === "/home" ? "/" : href}
className={`${isActive && "nav_item_active"} nav_item`}>
<span>{text}</span>
</a>
</Link>
);
}
In this, we check if the current router path is the same as the href
then return true
for isActive
and if the current route is active then apply the nav_item_active
class.
This is all we need to create an active navigation bar and it works flawlessly. You can check the live demo on the following sandbox.
Wrapping Up
If you enjoyed this article then don't forget to press โค๏ธ and Bookmark it for later use. If you have any queries or suggestions don't hesitate to drop them. See you.
You can extend your support by buying me a Coffee.๐๐
My Newsletter
Top comments (6)
A great suggestion thank you!
I usually wrap around the whole app with a common context which helps me in checking the active navigation along with sub-navs!
This is a simpler approach and will likely use it in simpler apps!
Thanks again! โจ
Yeah, Context works too, but for simpler projects I use this approach which works same as the context. I am glad you liked it :)
This works wonderfully well!
Yes it works. There could be bunch of other ways but I like this one.
A bit more challenging task would be to create breadcrumbs for navigation.
It could be challenging, but it totally depends on your navigation or route structure. If it is super complex then it'll be hard otherwise it won't be that hard.