Chen Yang

Highlight Nav Link for Current Page in Astro

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>