This article is about how to give the navigation items for each page in the new static site generator - Astro - an active-state style. (What a long sentence. 😮💨)
And there are two ways. (These code are written in Astro Component.)
The Old Good JavaScript Way
In the code below, we write the vanilla JavaScript in a script
tag, which tells Astro to give this code block to the browser. It will work in a regular way.
// src/components/Navbar.astro
<nav>
<a class="active" href="/">Home</a>
<a href="/portfolio">Portfolio</a>
<a href="/posts">Article</a>
<a href="/about">About Me</a>
<a href="/contact">Contact Me</a>
</nav>
<script>
const navLinks = document.querySelectorAll("nav a");
navLinks.forEach((link) => {
link.classList.remove("active");
// `slice` here to remove the first `/` in pathname
const currentPath = window.location.pathname.slice("1");
// `link.href` returns a whole url, such as: "https://somedomain.com/posts" and we only need the last part
const hrefArray = link.href.split("/");
const thisPath = hrefArray[hrefArray.length - 1];
if (currentPath === thisPath) {
link.classList.add("active");
}
});
</script>
The Astro Way
We take advantage of Astro's Runtime API and get the pathname in Astro components' component script.
// src/components/Navbar.astro
---
const pathname = new URL(Astro.request.url).pathname;
const currentPath = pathname.slice(1); // remove the first "/"
---
<nav>
<a class={currentPath === "" ? "active" : ""} href="/">Home</a>
<a class={currentPath === "portfolio" ? "active" : ""} href="/portfolio">Portfolio</a>
<a class={currentPath === "posts" ? "active" : ""} href="/posts">Article</a>
<a class={currentPath === "about" ? "active" : ""} href="/about">About Me</a>
<a class={currentPath === "contact" ? "active" : ""} href="/contact">Contact Me</a>
</nav>