Add style to your header navigation active menu link

menu

If you wish to offer users, more clear information about the menu item they are visiting, then try this code: (it does not work with sub-menu items…yet)

Add this code to the custom code section /header of your softr app:

<script>
// Add special class to active nav menu link for better UX

window.addEventListener('block-loaded-YOUR-BLOCK-ID', function() {
    highlightSelectedLink();
});
window.addEventListener('block-loaded-YOUR-BLOCK-ID2', function() {
    highlightSelectedLink();
});

function highlightSelectedLink() {
    const headerElements = document.querySelectorAll('header');
    const config = { childList: true, subtree: true };
    const callback = (mutationList, observer) => {
            document.querySelectorAll('header a').forEach((el)=> 
                { 
                    let href = el.getAttribute('href');
                    
                    if(href && window.location.pathname.startsWith(href)) 
                        { 
                            const span = el.querySelector('span');
                            
                            if (span) {
                                for (let i =  span.classList.length - 1; i >= 0; i--) {
                                    const className = span.classList[i];
                                    if (className.startsWith('sw-text-color-')) {
                                        span.classList.remove(className);
                                    }
                                }
                                span.classList.add("active-link");
                            }
                        }
                
                });
        };

    const observer = new MutationObserver(callback);

    headerElements.forEach((he) => {
        observer.observe(he, config);
    });
}
</script>

<style>
.active-link {
  position: relative;
  color: #f0f3d5; /* text color */
  text-decoration: none;
  padding: 8px 8px; /* padding of the box*/
  
}

/* style for the active-link box */
.active-link::before {
  content: "";
  position: absolute;
  top: -5px; 
  left: -5px; 
  width: calc(100% + 10px); 
  height: calc(100% + 10px); 
  background-color: #878874; /* Main bg color */
  opacity: 0.9; /* control opacity */
  z-index: -1;
}
</style>
1 Like

Thanks for sharing this @acjnas looks smooth!

Nice one - wanted this feature for ages. Hope your hard work results in Softr adopting it as native! Def need better contextual feedback on where the user is…the recent headers and sub-head content types helped…

I Used this script and it was working fine. But its not working suddenly, I haven’t changed anything, not the block name or anything.

.active-link { color: #5400ae !important; }

This is my code, ‘header1’ is my block id. Could you pls take a look at this.

Hey @Siva , let us check this and get back to you with updates!

Hey guys! Thank you for trying my code.

Here is an updated version that works better. Please try and comment:

<!-- START custom Active state for nav bar menu items + hover state -->
<script>
// Add special class to active nav menu link for better UX
// Added an exception to protect links with word 'ingresar' not to change on hover
// Added support to also hover on sub-menu links

window.addEventListener('block-loaded-home-header3', function() {
    highlightSelectedLink();
});
window.addEventListener('block-loaded-home-header1', function() {
    highlightSelectedLink();
});
window.addEventListener('block-loaded-home-header4', function() {
    highlightSelectedLink();
});

function highlightSelectedLink() {
    const headerElements = document.querySelectorAll('header');
    const config = { childList: true, subtree: true };
    const callback = (mutationList, observer) => {
        document.querySelectorAll('header a').forEach((el) => {
            let href = el.getAttribute('href');
            let innerText = el.innerText.toLowerCase().trim(); // Get inner text and convert to lowercase

            if (href && window.location.pathname.startsWith(href) && innerText !== 'ingresar') {
                const span = el.querySelector('span');

                if (span) {
                    for (let i = span.classList.length - 1; i >= 0; i--) {
                        const className = span.classList[i];
                        if (className.startsWith('sw-text-color-')) {
                            span.classList.remove(className);
                        }
                    }
                    span.classList.add("active-link");
                }
            }

            // On mouse enter, add "active-link-hover" class
            // only for inner text not equal to 'ingresar'
            el.addEventListener('mouseover', function() {
                if (this.innerText.toLowerCase().trim() !== 'ingresar') {
                    const span = this.querySelector('span');
                    if (span) {
                        span.classList.add("active-link-hover");
                    }
                }
            });

            // On mouse out, remove "active-link-hover" class
            el.addEventListener('mouseout', function() {
                if (this.innerText.toLowerCase().trim() !== 'ingresar') {
                    const span = this.querySelector('span');
                    if (span) {
                        span.classList.remove("active-link-hover");
                    }
                }
            });
        });
    };

    const observer = new MutationObserver(callback);
    headerElements.forEach((he) => {
        observer.observe(he, config);
    });
}
</script>

<!-- CSS STYLES -->

<style>
.active-link {
  position: relative;
  color: #f0f3d5; /* default color text */
  text-decoration: none;
  padding: 8px 8px; /* Add padding a left right - Top Bottom*/
  z-index:2;
}

/* Style for the hover effect */
.active-link::before {
  content: "";
  position: absolute;
  top: -5px; /* Ajusta la posición superior según sea necesario */
  left: -5px; /* Ajusta la posición izquierda según sea necesario */
  width: calc(100% + 10px); /* Ajusta el ancho según sea necesario */
  height: calc(100% + 10px); /* Ajusta la altura según sea necesario */
  background-color: #878874; /* Default bg color */
  opacity: 0.9; /* Adjust opacity */
  z-index: -1;
  border-radius: 5px;
}

.active-link-hover {
  position: relative;
  color: #ffffff; /* Default color text */
  text-decoration: none;
  padding: 8px 8px; /* Add padding a left right - Top Bottom*/
  z-index:2;
}

.active-link-hover::before {
  content: "";
  position: absolute;
  top: -5px; /* Ajusta la posición superior según sea necesario */
  left: -5px; /* Ajusta la posición izquierda según sea necesario */
  width: calc(100% + 10px); /* Ajusta el ancho según sea necesario */
  height: calc(100% + 10px); /* Ajusta la altura según sea necesario */
  background-color: #cdcebc; /* Default bg color */
  opacity: 0.9; /* Adjust opacity */
  z-index: -1;
  border-radius: 5px;
}
</style>

<!-- END custom Active state for nav bar menu items + hover state -->
1 Like