'Active nav item with custom html elements

I'm building a nav component using html custom elements like so:

HTML

<app-navbar></app-navbar>
<template>
<style>
    ul {
        display: flex;
        list-style: none;
        gap: 20px;
    }
    a {
        padding: 10px;
        text-decoration: none;
    }
    .active {
        color: white;
        background-color: red;
    }
</style>
<nav>
    <ul>
        <li><a href="/page-one.html">Nav item 1</a></li>
        <li><a href="/page-two.html">Nav item 2</a></li>
        <li><a href="/page-three.html">Nav item 3</a></li>
    </ul>
</nav>

JS

class AppNavBar extends HTMLElement { 
 constructor() { 
  super();
  this.attachShadow({ mode: 'open' });
  const template = document.querySelector('template');
  this.shadowRoot.appendChild(template.content.cloneNode(true))
 }
}
window.customElements.define("app-navbar", AppNavBar)

And now I need to pass the active class onto the respective nav item. For example when click on <a href="/page-two.html">Nav item 2</a> I want that item to get the class .active and so on.

Update

Something like:

page-one.html

<app-navbar page-one-nav-item="active"></app-navbar>

page-two.html

<app-navbar page-two-nav-item="active"></app-navbar>

page-three.html

<app-navbar page-three-nav-item="active"></app-navbar>

Is this possible to achieve with html custom elements?

Thank you.



Solution 1:[1]

If you want to do it with a Web Component, wrap the <a> in a Web Component:

<nav-a href="/page-one.html">Nav item 1</nav-a>

console.log(location);
customElements.define("nav-a", class extends HTMLElement {
  connectedCallback() {
    setTimeout(() => { // make sure innerHTML is parsed
      let href = this.getAttribute("href");
      let klass = (location.href.includes(href)) ? "active" : "";
      this.innerHTML = `<a class="${klass}" href="${href}">${this.innerHTML}</a>`;
    });
  }
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1