Skip to content

Custom lovelace card that displays a bottom nav in mobile devices, and a side nav in desktop devices for easy navigation.

Notifications You must be signed in to change notification settings

joseluis9595/lovelace-navbar-card

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

72 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Navbar Card

Buy me a beer Last commit Downloads Version HA Community forum

navbar-card-github

Navbar Card is a custom Lovelace card designed to simplify navigation within your Home Assistant dashboard, heavily inspired by the great work of Adaptive Mushroom and Google's Material Design. It provides a sleek, responsive navigation bar that displays as a full-width bar at the bottom on mobile devices. On desktop, it adapts into a flexible container that can be positioned on any side of the screen (top, bottom, left, or right) adjusting its orientation to fit seamlessly.


Installation β€’ Quickstart β€’ Configuration β€’ Dashboard adjustements β€’ Example configurations β€’ Help β€’ Donate




πŸš€ Installation

Open in HACS (recommended)

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

HACS manual configuration
  1. Go to HACS in Home Assistant.
  2. On the top right, click "Custom repositories".
  3. Enter the repository URL: https://github.com/joseluis9595/lovelace-navbar-card.git
  4. Search for "Navbar Card".
  5. Click Install!
Manual installation without HACS
  1. Download navbar-card.js from the latest release.
  2. Move this file to home assistant's <config>/www folder.
  3. In home assistant, go to Settings > Dashboards.
  4. On the top right corner, click Resources.
  5. Add a new resource with the following:
    • URL: /local/navbar-card.js
    • Resource type: JavaScript module
  6. Go to your dashboard, refresh your page and add your new navbar-card!



⚑ Quickstart

  1. Edit your Home Assistant dashboard: Go to your dashboard in Home Assistant and enter edit mode.
  2. Add the Navbar Card: Click to add a new card, search for "navbar-card", and add it anywhere in your dashboard layout (doesn't matter where, navbar-card will automatically float to the bottom on mobile devices, and to the position you have configured for desktop devices).
  3. Configure your routes: In the card configuration, define a few routes to the views you want quick access to. For example:
type: custom:navbar-card
routes:
  - url: /lovelace/home
    icon: mdi:home
    label: Home
  - url: /lovelace/lights
    icon: mdi:lightbulb-outline
    label: Lights
  - url: /lovelace/devices
    icon: mdi:devices
    label: Devices
  1. Save and enjoy: Save your dashboard. The navbar will now appear and let you quickly switch between your configured views!



βš™οΈ Configuration

navbar-card
Name Type Default Description
routes Routes Required Defines the array of routes to be shown in the navbar
desktop Desktop - Options specific to desktop mode
mobile Mobile - Options specific to mobile mode
template Template - Template name
layout Layout - Layout configuration options
styles Styles - Custom CSS styles for the card
haptic Haptic - Fine tune when the haptic events should be fired in the card

Routes

Routes represents an array of clickable icons that redirects to a given path. Each item in the array should contain the following configuration:

Name Type Default Description
url string Required* The path to a Lovelace view. Ignored if tap_action is defined.
icon string | JSTemplate - Material icon to display as this entry icon. Either icon or image is required.
icon_selected string | JSTemplate - Icon to be displayed when url matches the current browser URL
image string | JSTemplate - URL of an image to display as this entry icon. Either icon or image is required.
image_selected string | JSTemplate - Image to be displayed when url matches the current browser URL
badge Badge - Badge configuration
label string | JSTemplate - Label to be displayed under the given route if show_labels is true
tap_action tap_action - Custom tap action configuration.
hold_action hold_action - Custom hold action configuration.
double_tap_action double_tap_action - Custom double_tap action configuration.
popup Popup items - List of routes to display in a popup menu
hidden boolean | JSTemplate - Controls whether to render this route or not
selected boolean | JSTemplate - Controls whether to display this route as selected or not. If not defined, the selected status will be computed as route.url == window.location.pathname

Note: url is required unless tap_action, hold_action, double_tap_action or popup is present.

Note: If tap_action is defined, url is ignored.


Tip: Some suggestions when using the image property:

  1. Place your custom images in the <ha-config-folder>/www directory
  2. Use images with a transparent background for best results
  3. Keep image dimensions squared for best results

Actions

Apart from the standard Home Assistant actions (navigate, call-service, etc.), navbar-card supports some additional custom actions:

Action Description Required Parameters
open-popup Opens the popup menu defined in the route None
toggle-menu Opens the native HA side menu None
show-notifications Opens the native HA notifications drawer None
quickbar Opens the native HA quickbar mode: entities | commands | devices
navigate-back Navigates back to the previous page in the browser history None
open-edit-mode Opens the current dashboard in edit mode None

Example:

type: custom:navbar-card
...
routes:
  ...
  - url: /lovelace/lights
    icon: mdi:lightbulb-outline
    tap_action:
      action: open-popup # Will open the popup menu defined for this route
    double_tap_action:
      action: quickbar # Will open the native HA quickbar
      mode: entities
    hold_action:
      action: toggle-menu # Will open the native HA side menu
  - icon: mdi:pencil
    tap_action:
      action: open-edit-mode

Badge

Configuration to display a small badge on any of the navbar items.

navbar-card_badges
Name Type Default Description
show boolean | JSTemplate false Boolean template indicating whether to display the badge or not
color string | JSTemplate red Background color of the badge
count string | JSTemplate - Text to be displayed inside the badge
textColor string | JSTemplate - Color for the text displayed inside the badge

Popup Items

For each route, a popup menu can be configured, to display a popup when clicked. This is activated using the open-popup action in either tap_action or hold_action.

navbar-card_popup
Name Type Default Description
url string Required* The path to a Lovelace view. Ignored if tap_action is defined.
icon string | JSTemplate - Material icon to display as this entry icon.
icon_selected string | JSTemplate - Icon to be displayed when url matches the current browser URL
image string | JSTemplate - URL of an image to display as this entry icon.
image_selected string | JSTemplate - Image to be displayed when url matches the current browser URL
badge Badge - Badge configuration
label string | JSTemplate - Label to be displayed under the given route if show_labels is true
tap_action tap_action - Custom tap action configuration, including 'open-popup' to display a popup menu.
hold_action hold_action - Custom hold action configuration, including 'open-popup' to display a popup menu.
selected boolean | JSTemplate - Controls whether to display this item as selected or not. If not defined, the selected status will be computed as item.url == window.location.pathname

Note: url is required unless tap_action is present. If tap_action is defined, url is ignored.

JSTemplate

You can easily customize some properties of the navbar-card by writing your own JavaScript rules. To do this, you simply wrap the value of the field that supports JSTemplates in [[[ and ]]], then write the JavaScript code that determines the property's value.

Apart from using plain javascript, you can access some predefined variables:

  • states -> Contains the global state of all entities in HomeAssistant. To get the state of a specific entity, use: states['entity_type.your_entity'].state.
  • user -> Information about the current logged user.
  • navbar -> Internal state of the navbar-card. Accessible fields are:
    • isDesktop -> Boolean indicating whether the card is in its desktop variant or not.

Tip: You can use console.log in your JSTemplate to help debug your HomeAssistant states.

Below is an example using JSTemplates for displaying a route only for one user, and a label indicating the number of lights currently on:

type: custom:navbar-card
desktop:
  position: bottom
  show_labels: true
routes:
  - url: /lovelace/lights
    label: |
      [[[ 
        const lightsOn = Object.entries(states)
          .filter(([entityId, value]) => {
            return entityId.startsWith('light.') && value.state == 'on';
          })
          .length;
        return `Lights (${lightsOn})` 
      ]]]
    icon: mdi:lightbulb-outline
    icon_selected: mdi:lightbulb
    hidden: |
      [[[ return navbar.isDesktop; ]]]
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
    hidden: |
      [[[ return user.name != "jose"; ]]]

Desktop

Specific configuration for desktop mode.

navbar-card_desktop
Name Type Default Description
show_labels boolean | popup_only | routes_only false Whether or not to display labels under each route
min_width number 768 Screen size from which the navbar will be displayed as its desktop variant
position top | bottom | left | right bottom Position of the navbar on desktop devices
hidden boolean | JSTemplate false Set to true to hide the navbar on desktop devices

Mobile

Specific configuration for mobile mode.

navbar-card_mobile
Name Type Default Description
show_labels boolean | popup_only | routes_only false Whether or not to display labels under each route
hidden boolean | JSTemplate false Set to true to hide the navbar on mobile devices
mode docked | floating docked Choose visualization mode on mobile devices. docked for default experience, floating for desktop-like visualization

Haptic

Controls when haptic feedback is triggered. You can either use a boolean to enable/disable all haptic feedback, or specify which actions should trigger haptic feedback:

Option Type Default Description
url boolean false Trigger when navigating to a new page
tap_action boolean false Trigger on tap actions
hold_action boolean false Trigger on hold actions
double_tap_action boolean false Trigger on double tap actions

Template

Templates allow you to predefine a custom configuration for navbar-card and reuse it across multiple dashboards. This approach saves time and simplifies maintenance β€” any change to the template will automatically apply to all cards using it.

Defining Templates

To define custom templates, add them under navbar-templates in your main Lovelace YAML configuration like this:

navbar-templates:
   your_template_name:
      # Your navbar config
      routes:
         - label: Home
           icon: mdi:home
           url: /lovelace/home
         ...
# Your normal lovelace configuration
views:
...

Referencing Templates

You can reference a template from your navbar-card using the template property:

type: custom:navbar-card
template: your_template_name

Overriding props

Card properties defined directly in the card will take priority over those inherited from the template.

For example, if you want to use a template called your_template_name but have one specific dashboard with a different primary color, your configurations might look like this:

  • Default Navbar for Most Views:
type: custom:navbar-card
template: your_template_name
  • Customized Navbar for a Specific View:
type: custom:navbar-card
template: your_template_name
styles: |
  .navbar {
    --navbar-primary-color: red;
  }

Layout

Configuration options for the navbar layout and behavior.

Name Type Default Description
auto_padding Auto Padding - Add padding to your Home Asistant dashboard to prevent overlaps

Auto Padding

Automatically adds padding to your Home Assistnat dashboard to prevent cards from overlapping with navbar-card. This eliminates the need for manual CSS padding adjustments in your Home Assistant theme.

Name Type Default Description
enabled boolean true Whether to automatically add padding to prevent overlaps
desktop_px number 100 Padding in pixels for desktop mode (applied to left/right based on position)
mobile_px number 80 Padding in pixels for mobile mode (applied to bottom)

Note: The desktop_px padding is automatically applied to the appropriate side based on your navbar's desktop.position setting.


Styles

Custom CSS styles can be applied to the Navbar Card to personalize its appearance and adapt it to your dashboard's design. Simply provide a CSS string targeting the relevant classes to style the navbar to your liking.

You can check out some examples here for inspiration.

Targetable Classes

Here is a breakdown of the CSS classes available for customization:

  • .navbar: Base component for the navbar.

    • .navbar.desktop: Styling for the desktop version.
    • .navbar.desktop.[top | bottom | left | right]: Specific styles for different positions of the navbar.
    • .navbar.mobile: Styling for the mobile version.
    • .navbar.mobile.floating: Styling for the mobile version when using floating mode.
  • .route: Represents each route (or item) within the navbar.

  • .button: Background element for each icon.

    • .button.active: Applies when a route is selected.
  • .icon: Refers to the ha-icon component used for displaying icons.

    • .icon.active: Applies when a route is selected.
  • .image: Refers to the img component used for displaying route images.

    • .image.active: Applies when a route is selected.
  • .label: Text label displayed under the icons (if labels are enabled).

    • .label.active: Applies when a route is selected.
  • .badge: Small indicator or badge that appears over the icon (if configured).

    • .badge.active: Applies when a route is selected.
  • .navbar-popup: Main container for the popup.

  • .navbar-popup-backdrop: Backdrop styles for the popup.

  • .popup-item: Styles applied to the container of each popup-item. This object contains both the "button" with the icon, and the label.

    • .popup-item.label-[top | bottom | left | right]: Specific styles for different positions of the label.
    • .popup-item .label: Styles applied to the label of each popup item.
    • .popup-item .button: Button for each popup item, containing just the icon.



πŸ› οΈ Dashboard adjustements

Padding

If you're using the Navbar Card, you might notice it could collide with other cards on your dashboard. The navbar-card now includes an automatic padding feature that handles this for you, eliminating the need for manual CSS adjustments.

Automatic Padding (Recommended)

The navbar-card automatically adds appropriate padding to prevent overlaps:

  • Desktop: Adds padding to the left or right side based on your navbar position
  • Mobile: Adds bottom padding to prevent cards from overlapping the bottom navbar

This feature is enabled by default, but you can customize it using the layout.auto_padding configuration. More info here

Manual Adjustement (Legacy)

If you prefer to handle padding manually or need more control, you can disable automatic padding and use CSS instead:
type: custom:navbar-card
layout:
  auto_padding:
    enabled: false # Disable automatic padding

Then use card-mod with a custom theme to add manual padding:

your_theme:
  card-mod-theme: your_theme
  card-mod-root-yaml: |
    .: |
      /* Add padding to the left (or other sides, depending on your navbar position) for desktop screens */
      @media (min-width: 768px) {
        :not(.edit-mode) > #view {
          padding-left: 100px !important;
        }
      }

      /* Add bottom padding for mobile screens to prevent cards from overlapping with the navbar */
      @media (max-width: 767px) {
        :not(.edit-mode) > hui-view:after {
          content: "";
          display: block;
          height: 80px;
          width: 100%;
          background-color: transparent; 
        }
      }

Hiding native tabs

Another useful styling detail, is removing the native ha-tabs element on the top of the screen. We want to hide the ha-tabs element, but keep the edit, search and assist buttons visible. To do so, once again, using card-mod and custom themes is quite easy:

For Home Assistant < 2025.0

your_theme:
  app-header-background-color: transparent
  app-header-text-color: var(--primary-text-color)

  card-mod-theme: your_theme
  card-mod-root-yaml: |
    .: |
      ha-tabs {
        pointer-events: none;
        opacity: 0;
      }

For Home Assistant β‰₯ 2025.0

your_theme:
  app-header-background-color: transparent
  app-header-text-color: var(--primary-text-color)

  card-mod-theme: your_theme
  card-mod-root-yaml: |
    .: |
      .toolbar > sl-tab-group {
        pointer-events: none;
        opacity: 0;
      }



πŸ“š Example Configurations

Basic example
type: custom:navbar-card
layout:
  auto_padding:
    enabled: true
    desktop_px: 100
    mobile_px: 80
desktop:
  position: left
  min_width: 768
  show_labels: true
mobile:
  show_labels: false
routes:
  - icon: mdi:home-outline
    icon_selected: mdi:home-assistant
    url: /lovelace/home
    label: Home
  - icon: mdi:devices
    url: /lovelace/devices
    label: Devices
    hold_action:
      action: navigate
      navigation_path: /config/devices/dashboard
  - icon: mdi:thermometer
    url: /lovelace/weather
    label: Weather
  - icon: mdi:creation-outline
    icon_selected: mdi:creation
    url: /lovelace/control
    label: Control
  - icon: mdi:dots-horizontal
    label: More
    tap_action:
      action: open-popup
    popup:
      - icon: mdi:cog
        url: /config/dashboard
      - icon: mdi:hammer
        url: /developer-tools/yaml
      - icon: mdi:power
        tap_action:
          action: call-service
          service: homeassistant.restart
          service_data: {}
          confirmation:
            text: Are you sure you want to restart Home Assistant?
    badge:
      show: >
        [[[ return states['binary_sensor.docker_hub_update_available'].state === 'on' ]]]
      color: var(--primary-color)

Examples with custom styles

Custom primary color
type: custom:navbar-card
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
styles: |
  .navbar {
    --navbar-primary-color: red;
  }

custom_primary_colors

Custom background color
type: custom:navbar-card
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
styles: |
  .navbar {
    background: #000000;
  }

custom_background

No rounded corners only in desktop mode
type: custom:navbar-card
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
styles: |
  .navbar.desktop{
    border-radius: 0px;
  }

border_radius

More spacing on desktop mode and "bottom" position
type: custom:navbar-card
desktop:
  position: bottom
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
styles: |
  .navbar.desktop.bottom {
    bottom: 100px;
  }

bottom_padding

Custom auto-padding configuration
type: custom:navbar-card
layout:
  auto_padding:
    enabled: true
    desktop_px: 150 # Extra wide padding for desktop
    mobile_px: 120 # Extra tall padding for mobile
desktop:
  position: right # Padding will be applied to the right
  show_labels: true
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
Display route only for a given user
type: custom:navbar-card
desktop:
  position: bottom
routes:
  - url: /lovelace/home
    label: Home
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
  - url: /lovelace/settings
    label: Settings
    icon: mdi:cog
    # This route will only be displayed for user "jose"
    hidden: |
      [[[ return user.name != "jose"]]]
Force one route to always be selected
type: custom:navbar-card
desktop:
  position: bottom
routes:
  - url: /lovelace/home
    label: Home
    selected: true # force `selected` field to true
    icon: mdi:home-outline
    icon_selected: mdi:home-assistant
  - url: /lovelace/devices
    label: Devices
    icon: mdi:devices
  - url: /lovelace/settings
    label: Settings
    icon: mdi:cog
Route with rounded user's image
type: custom:navbar-card
routes:
  - image: |
      [[[ 
        return hass.states["person.jose"].attributes.entity_picture
      ]]]
    label: More
    tap_action:
      action: open-popup
    popup:
      - icon: mdi:cog
        url: /config/dashboard
      - icon: mdi:hammer
        url: /developer-tools/yaml
      - icon: mdi:power
        tap_action:
          action: call-service
          service: homeassistant.restart
          service_data: {}
          confirmation:
            text: Are you sure you want to restart Home Assistant?
styles: |
  .image {
    border-radius: 16px !important;
  }



πŸ’¬ Help

Need help using navbar-card, have ideas, or found a bug? Here's how you can reach out:

Your feedback helps make navbar-card better for everyone. Don’t hesitate to reach out!




🍻 Donate

If you enjoy using navbar-card and want to support its continued development, consider buying me a coffee (or a beer 🍺), or becoming a GitHub Sponsor!

Buy Me A Coffee GitHub Sponsors

Your support means a lot and helps keep the project alive and growing. Thank you! πŸ™Œ

About

Custom lovelace card that displays a bottom nav in mobile devices, and a side nav in desktop devices for easy navigation.

Topics

Resources

Contributing

Stars

Watchers

Forks

Sponsor this project

  •