🧭 Navbar card: easily navigate through dashboards

Just started to use the mediaplayer option, love it!

When turning on album cover as background the edges gets square:ish on my mobile (iOS), but looks nice and round on desktop. With album cover turned off it is fine on both.

Anything on my side or is this a small cosmetic bug?

2 Likes

I love my navbar-card. So far I have gotten it to do everything I want. The time and date feature is the final thing on my list! I literally check this thread every so often just to see if there is any chatter about it. Keep us posted and thank you!

I love the new media player! Is there any way to just(!) have the media player? Without the actual navbar with routes etc.?

Same here! But i had it already before the latest update.

Thanks for a great card! Works perfectly on phone and desktop

However, when casting it to a Nest hub, it always overlaps the content, regardless of values of auto_padding: true, desktop_px, etc (also regardless of placing, like left or top)

I have also tried styling it with css but to no effect

Is anyone else using with a casted dashboard? And do you have any advice on the matter? :slight_smile:

Hi,
this code works for me.

icon: |-
  [[[var climateCount = Number(states['sensor.heizung_an'].state);
      if (climateCount === 0) 
        { return 'mdi:radiator-off' } 
      else if (climateCount > 0) 
        { return 'mdi:radiator' } 
      else 
      { return 'mdi:alert-circle-outline' }
]]]

anyone managed to copy the style of ios26 navbar?

3 Likes

How to use a navbar template with extended routes per view?

I have create a navbar template and I’ve added it to all the view of a dashboard. It’s just working great.

And now, for some of my view, I would like to add some routes to the particular navbar card of each view while still benefiting from all the routes and stuff I’ve already configured in the template.

But I can’t figure out how to achieve that - any hints?

Well using it right now but with combination of bubble card horizontal stack bar which offers auto reording feature for room activities when binary sensors detect movement. Anyway...
i only look for bettr a way to dynamicaly show mediaplayer cover as menu button and once clicked it could popup to this media player but not sure if possible

thank you anyway

Hey everyone!

First and foremost I would like to thanks Jose Luis for his amazing work with this card. It's a pillar of my dashboard.

With that said, I was trying to see if anyone could help me sort something out. I was using the bottom bar for my wall tablet but it was overlaping some elements, so I decided to move it to the left. Everything looked great on my PC, but then when I checked my slightly more squarish wall-tablet, one of the sections was pushed back. Anyone has an idea on how to fix this? TIA!

For some reason alot of the text boxes are not options to be typed in and all the toggle switches are grayed oujt and i can not toggle them on? Any Suggestions

1 Like

Yep same for me, have to do those options via YAML instead then it works.

Indeed.... The advanced UI options/templating is broken.
I also get console errors about the map-thing, which gives a 404.

Can i ask how you made the social,quatros,outro button?

Just want to share a hack to get badge icons instead for numbers.
Me myself and claude did this so be kind. Anyone who actually know javascript and css is more then welcome to correct it, but it works.

I added this as a resource in dahsboard. /local/navbar-badge-icons.js and the file in the www folder

// www/navbar-badge-icons.js
(function () {
    // Global registry: routeIndex -> desired icon
    window.__navbarBadgeIcons = window.__navbarBadgeIcons || {};

    // This is the function you call from your YAML templates
    window.setNavbarBadgeIcon = function (routeIndex, iconName) {
    window.__navbarBadgeIcons[routeIndex] = iconName || null;
    return ""; // so you can return the result directly in e.g. count:
    };

    function findNavbarCards(root, found = []) {
    root.querySelectorAll("*").forEach((el) => {
        if (el.localName === "navbar-card") found.push(el);
        if (el.shadowRoot) findNavbarCards(el.shadowRoot, found);
    });
    return found;
    }

    function applyIcons(navbarCard) {
    if (!navbarCard.shadowRoot) return;
    const routes = navbarCard.shadowRoot.querySelectorAll(".route");

        routes.forEach((route, index) => {
            const badge = route.querySelector(".badge");
            const desiredIcon = window.__navbarBadgeIcons[index];

            if (!badge) return;

            // No icon wanted for this route -> make sure any old icon is removed
            if (!desiredIcon) {
            const existing = badge.querySelector(".custom-badge-icon");
            if (existing) {
                existing.remove();
                badge.style.fontSize = "";
            }
            return;
            }

            let iconEl = badge.querySelector(".custom-badge-icon");
            if (!iconEl) {
            badge.style.fontSize = "0";
            badge.style.setProperty("width", "19px", "important");
            badge.style.setProperty("height", "18px", "important");
            badge.style.display = "flex";
            badge.style.alignItems = "center";
            badge.style.justifyContent = "center";
            iconEl = document.createElement("ha-icon");
            iconEl.className = "custom-badge-icon";
            iconEl.style.cssText = `
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 16px;
                height: 16px;
                --mdc-icon-size: 16px;

            `;
            iconEl.style.setProperty("--icon-primary-color", "black", "important");
            badge.appendChild(iconEl);
            }
            // Only update if the icon actually changed (e.g. lock -> lock-open)
            if (iconEl.getAttribute("icon") !== desiredIcon) {
            iconEl.setAttribute("icon", desiredIcon);
            }
        });
    }

    function scanAndApply() {
    findNavbarCards(document.body).forEach((card) => {
        applyIcons(card);
        if (!card.__badgeIconObserver) {
        const obs = new MutationObserver(() => applyIcons(card));
        obs.observe(card.shadowRoot, { childList: true, subtree: true });
        card.__badgeIconObserver = obs;
        }
    });
    }

    scanAndApply();
    new MutationObserver(() => scanAndApply()).observe(document.body, {
    childList: true,
    subtree: true,
    });

    // Extra safety net: templates may run before the DOM has finished
    // mutating, so we also run a quick follow-up check.
    window.setNavbarBadgeIcon = new Proxy(window.setNavbarBadgeIcon, {
    apply(target, thisArg, args) {
        const result = target.apply(thisArg, args);
        requestAnimationFrame(scanAndApply);
        return result;
    },
    });
})();

And then this in the navbar card under routes->badge->count (I think you should be able to put it in “css styles” but i had issues with that.)

return window.setNavbarBadgeIcon(
    3,
    hass.states['sensor.garage_door_state']?.state === 'closed'
      ? 'mdi:garage'
      : 'mdi:garage-open'
  );

The number is the position of the route, in this case the 4th position.(0,1,2,3) and the second part is the icon you want.

Hello,
How to have the media bar always visible, even when there is no music playing?