💡 UIX Forge - template cards, badges, rows, picture-elements, sections and add Sparks

UIX Forge (custom:uix-forge), part of UI eXtension, is a custom Lovelace element that combines template-driven configuration with additional behaviours called sparks. Use it to:

  • Forge any standard Home Assistant element from templates, allowing the entire element config to react to entity states, user, browser and other template variables.
  • Add sparks — self-contained behaviours such that augment the forged element.
  • Apply UIX Styling to the forged element, exactly like any other element. Additionally any spark variables and made available in uixForge template variable.

Base structure (no templates)

type: custom:uix-forge
forge:
  mold: card
element:
  type: tile
  entity: light.living_room
  uix:
    style: |
      ha-card {
        --tile-color: teal;
      }

forge: does the heavy lifting, taking the element config and creating a forged element.

element: element config where ALL CONFIG can accept Home Assistant Jinja templates.

mold: every forge needs a mold and no different here. The mold is used by the forge to know how to forge the element such that it works in place where it is used. molds supported are card, badge, row, picture-element and section. Note: no guess work is done by the forge, you always need to specifically tell it the mold to use

forge config includes hidden, grid_options (card mold only) and sparks all which accept templates. All molds except section support visibility on the element so you can slide and dice how you wish to show your frontend elements, either using standard visibility config or the forge hidden config.

UIX Styling is supported on both the forge (uix-forge HTML element) and the forged element (Frontend element generated in shadow root of the forge).

:zap: Sparks

Every good forge needs a :zap: Spark or two. UIX Forge Sparks are optional behaviours added to a UIX Forge forged element via the forge.sparks list. Each spark has a type key and its own configuration options.

Available sparks:

  • :speech_balloon: Tooltip — attach a styled tooltip to any element within the forged element.
  • :stop_button: Button — insert an interactive ha-button element as a sibling after any element within the forged element.
  • :label: Attribute — add, replace or remove an attribute of any element within the forged element.
  • :zap: Event — receive DOM events from fire-dom-event actions and expose their data as template variables.
  • :star: Tile Icon — insert a ha-tile-icon element as a sibling before or after any element within the forged element.
  • :shield: State Badge — insert a state-badge element as a sibling before or after any element within the forged element.
  • :capital_abcd: Grid — apply CSS Grid layout to any container element within the forged element.
  • :mag: Search — find elements within a container by CSS selector and optional text filter, then apply class, attribute, or text mutations to all matches.
  • :world_map: Map — preserve the zoom level and centre of a map card across Home Assistant state updates.
  • :lock: Lock — overlay a lock icon on any element to block interaction until the user passes a PIN, passphrase, or confirmation challenge.

:zap: Spark highlights

  • Event spark brings the ability to change element config on the fly without relying on sensors. A great example is Using UIX Forge event spark to change a camera view
  • Grid spark allows for most of what custom:layout-card does for sections, giving an alternative for that custom card.
  • Lock spark allows to both unlock and execute the protected element action in one step. :white_check_mark:
  • Map spark, while simple, provides the required memory for a map card when using templates for config, meaning it does not reset view zoom and position every time the templae updates. :white_check_mark:
  • Tooltip spark - often requested action is to just have a tooltip. Combined with the attribute spark you can blow away the browser tooltips based on title attribute and add your own rich tooltips, all with templates supported.

UIX Forge now available and refined in UI eXtension 6.1.0

Thanks to @Mariusthvdb for testing many 6.1.0 betas :pray:

:question: Is there a Spark you desire :question: Add a Feature Request on GitHub and we can start the ball rolling.

6 Likes

:mega: 6.2.0-beta.5 - Lock spark updates and map tour mode :mega:

Lock spark icon when target ha-tile-icon

lock-spark-styling-example-2

Map tour

Apr-09-2026 19-35-40

Many thanks for this extension to the UIX integration - obviously brings so much potential, which I’m just slowly getting my head around.

One thing I’ve noticed (and this might just be me not getting it yet) is that it doesn’t seem to play nicely with Nerwyn’s Custom Features for Home Assistant Cards. This also allows templating from the custom feature’s configuration entity: {{ config.entity }}.

It seems that UIX is interpreting these templates as referring to the entity of the custom forge - there are complaints in the logs about missing entities if the forged element itself doesn’t have an entity for e.g. a Grid spark.

Using {{ config.element.entity }} instead in the custom feature configuration gets around this to an extent, but only where say the custom forge element has an entity which is the same as that on the custom feature, which is a long way from being the case all the time.

Am I missing something obvious here?

If you are forging an element which uses jinja handlebars you will need to nest your template. By default template nesting characters are << and >>. These are replaced as per info below shared from docs.

<< ‘Nested’  >>

When using template nesting, the template nesting characters are replaced with Jinja raw directives before the template is rendered. The replacement includes a marker for internal readiness code to be able to recognise a rendered template with nesting. << is replaced with {% raw %}{{{#uix#}{% endraw %} and >> is replaced with {% raw %}{#uix#}}}{% endraw %} .

EDIT: Nesting assumes that the element can handle Jinnah style comments. If ha-nunjucks does not then this could be an issue. The comment included is needed internally to UIXForge but could easily be stripped before forging the element. If this comment is not liked by ha-nunjucks then please raise an issue and I will work on a solution.

UPDATE: Looks like nunjucks supports comments so should be good but I have not tested.

Oh, so that’s what that bit of the docs is referring to. Of course!

Yes, just trying with nesting the templates, and it’s still not working. Likely for this reason. Before I submit an issue, is there a way I can provide relevant console logs for you? I can see how to debug UIX templates, but not foundries.

EDIT: just seen your UPDATE. Will keep trying then.

FURTHER EDIT: Couldn’t get it to work with << >> as nesting tags, but succeeded by writing out the {% raw %} {{ {% endraw %} {% raw %} }} {% endraw %} tags in full within the custom feature config.

FURTHER FURTHER EDIT: actually using explicit raw tags doesn’t work consistently. Will keep trying.

I noted my example was wrong. Updated now.

I would first try out nesting to a markdown card or something where you can see the result. Then you will get a visual view of what goes on behind the scenes.

When I am not responding while being an insomniac, I will write up a simple example using custom features.

1 Like

If you don’t have {#uix#} after the generated raw {{ or before the generated }} then forge template controller will think that template result has not come through for the template so will not get to a ready state.

Do you have simple config you are trying to test. Post it as an issue in GitHub and we can keep resolving from there.

EDIT: Ah, but this internal mechanism would mean a nested template may make the forge ready early when it is not so there is an issue to solve.

EDIT 2: Also a nested template on its own is not seen as a template so no template rendering taking place. Issue raised: [Bug]: Support custom features with templates · Issue #198 · Lint-Free-Technology/uix · GitHub

1 Like

@reste_narquois v6.2.0-beta.6 available with nesting support working correctly

type: custom:uix-forge
forge:
  mold: card
element:
  type: tile
  entity: light.bed_light
  vertical: false
  features:
    - type: custom:service-call
      entries:
        - type: button
          entity_id: light.kitchen_lights
          tap_action:
            action: toggle
            target:
              entity_id: |
                << config.entity >>
            data: {}
          icon: mdi:alarm-light
  features_position: bottom

See test showing light.kitchen_lights is being actioned. My test here was pretty simple to show that the entity is coming from the custom feature button config.

Apr-10-2026 19-00-31

Brilliant, thanks so much. Amazing support. Can confirm that this also works with the custom-features card:

type: custom:uix-forge
forge:
  mold: card
  uix:
    style:
      custom-features-card $: |
        ha-card {
          background: none;
          box-shadow: none;
        }
element:
  type: custom:custom-features-card
  features: 
    - type: custom:service-call
      entries:
        - type: button
          entity_id: input_boolean.display_kitchen_media_player_volume_mute
          icon: mdi:volume-high
          haptics: true
          tap_action:
            action: perform-action
            perform_action: input_boolean.toggle
            target:
              entity_id: |
                << config.entity >>

However, it doesn’t seem to work if I start nesting, for example here if I put the above configuration as the second card in a forged grid:

type: custom:uix-forge
forge:
  mold: card
  sparks:
    - type: grid
      for: "hui-grid-card $ #root"
      columns: "40% auto"
      column_gap: 0px
element:
  type: grid
  square: false
  cards:
    - type: custom:uix-forge
      foundry: tile_no_background_no_ripple
      element:
        entity: media_player.display_kitchen_media_player
        name: "Kitchen"
    - type: custom:uix-forge
      forge:
        mold: card
        uix:
          style:
            custom-features-card $: |
              ha-card {
                background: none;
                box-shadow: none;
              }
      element:
        type: custom:custom-features-card
        features: 
          - type: custom:service-call
            entries:
              - type: button
                entity_id: input_boolean.display_kitchen_media_player_volume_mute
                icon: mdi:volume-high
                haptics: true
                tap_action:
                  action: perform-action
                  perform_action: input_boolean.toggle
                  target:
                    entity_id: |
                        << config.entity >>

The nested foundry for the first tile card in the grid is working OK.

The end goal would be to have these all as foundries, with just the entity_id changing.

It’s great to see you are putting the forge through its paces.

I will need to support multiple nesting, kind of like how button card does it for JavaScript, but for Jinja. It will need careful thought with how the internals wait for initial templates so I will not rush.

Change ready for testing which will do tomorrow (evening here now in AUS).

1 Like

I’m trying out the auto-entities example from the UIX Forge documentation but it’s giving me an error in the rendering of the cards. This is a direct copy paste of the code. I get it for any of the defined areas that I have. I’m on the current release of uix (v6.1.0) and the new auto-entities (v2.1.0). Given that this is straight out of the documentation I would expect it to work

I tried this because my original intent, to use an entity_id with some globs instead of the area gave me the same error and I figured I should try something from the docs first

Needs latest beta.

Ok, that fixed it for me. Now to try putting together my real use case :slight_smile:

1 Like

v6.2.0-beta.7 available which implements multi-level forge nesting. The syntax extends existing single level nesting in that each level gains a <> pair.

Tetsed example
type: custom:uix-forge
forge:
  mold: card
  sparks:
    - type: grid
      for: "hui-grid-card $ #root"
      columns: 40% auto
      column_gap: 0px
element:
  type: grid
  square: false
  cards:
    - type: custom:uix-forge
      forge:
        mold: card
      element:
        type: tile
        entity: media_player.dcd_browser
        name: Kitchen
    - type: custom:uix-forge
      forge:
        mold: card
      element:
        type: custom:custom-features-card
        features:
          - type: custom:service-call
            entries:
              - type: button
                entity_id: input_boolean.test_boolean
                icon: mdi:volume-high
                haptics: true
                tap_action:
                  action: perform-action
                  perform_action: input_boolean.toggle
                  target:
                    entity_id: |
                      <<< config.entity >>>

Apr-11-2026 10-46-20

2 Likes

:bulb: Latest UIX Guide - Using UIX Forge event and button sparks to change inline tile card feature

1 Like

:mega: UI eXtension 6.2.0 released :mega:

All fixed/features are UIX Forge releated for this release.

:star: New Features

  • forge: extend nested template syntax to multiple layers for nested forges (e.g. 3 layers <<</>>>) (#202) (b1a6b62), closes #201
  • forge: Support UIX Forge to be card for auto-entities allowing and passing entities to forged element (daf383a)
  • lock-spark: Add --uix-lock-icon-background, --uix-lock-icon-border-radius, --uix-lock-icon-padding, and state-variant icon background CSS variables (#194) (3e2770c)
  • lock-spark: add color CSS vars for lock icon and set defaults when target is ha-tile-icon (#197) (701227b)
  • lock-spark: Allow for target to be ha-tile-icon to lock tile icon only (26dfa91)
  • lock: add CSS variable cursor control to lock spark overlay (#204) (0325409), closes #192
  • map-spark: Add fit_map option to map spark allowing to work around maps in custom cards which may initially hide map (e.g. auto-entities). (#195) (1a47b91)
  • map-spark: Add map spark tour mode (#196) (5a6db26)

:lady_beetle: Bug Fixes

  • beta: Don’t delete entities from config in case locked (8edf7bd)
  • beta: Regression with state_color causing configuration error (598e2cb)
  • forge: Fix template nesting not resolving correctly (db6ebce)

:gear: Miscellaneous

  • Add entity card support for auto-entities (9087bfc)
  • lock-spark: Adjust top/left lock icon when target is ha-tile-icon (f9d377f)

:bulb: Tooltip spark doco now with example animations :+1:

These are generated using a doc imaging build process in the UIX repo again a full Home Assistant server with demo: loaded using latest stable version, with UIX only added, and can be recreated with one command. :sunglasses:

Over the next week I will be adding images/animation to all Forge sparks so if you are yet to try them out, you will be able to see before you try.

UPDATE: Button sparks now done including the variant/appearance showing hover states. :white_check_mark: - Button spark - UI eXtension

Crosspost in UIX CSS styling thread as well to reply to ongoing questions about image/animation examples

Not sure if I’m doing something weird, but I’ve noticed that changing the value of the --uix-icon variable according to entity state is not working within a custom forge without a full dashboard refresh. The change is visible in Developer Tools, so it is being applied at the right DOM level, just not affecting the actual view.

Working code:

- type: tile
  uix:
    macros:
      icon_type:
        params:
          - entity_id
          - name: icon_on
            default: "'mdi:checkbox-outline'"
          - name: icon_off
            default: "'mdi:checkbox-blank-outline'"
        template: "{{ icon_on if is_state(entity_id, 'on') else icon_off }}"
    style: |
      :host {
        --uix-icon: {{ icon_type(config.entity) }};
      }
  entity: input_boolean.display_kitchen_media_player_include
  name: "Icon change not in forge (working)"

Non-working code:

- type: custom:uix-forge
  forge:
    mold: card
    uix:
      macros:
        icon_type:
          params:
            - entity_id
            - name: icon_on
              default: "'mdi:checkbox-outline'"
            - name: icon_off
              default: "'mdi:checkbox-blank-outline'"
          template: "{{ icon_on if is_state(entity_id, 'on') else icon_off }}"
      style:
        .: |
          :host {
            --uix-icon: {{ icon_type(config.element.entity) }};
          }
  element:
    type: tile
    entity: input_boolean.display_kitchen_media_player_include
    name: "Icon change in forge (not working)"

Is this expected? Or is my code faulty? To be fair, I have only tested this using macros, in case that makes a difference.

A few things to note:

  • --uix-icon binds itself to the closest uix style nodes <uix-node> (10 steps incluing shadow roots) and then will update on updates to styles in those style nodes. My testing shows that the forge uix is at step 10 and works for me. Regardless, see below for what you can do.
  • Generally you would place your uix styling on the element rather than the forge. With all the background smarts going on it may apear these are the one and the same, however there is <uix-forge> element which then encloses <element> in its shadow root using <hui-card>, here element being <hui-tile-card>. The only reasons you would place uix styling on forge would be to deal with a problematic custom card which can’t be styled, or you wished to use forge config, but no uses cases for that come to mind.
  • You can promote your macros to forge config and they can be used by forge and element, though do review this NOTE if to understand the different variable contexts. Included below is an example of placing macro in forge config and then using in uix styling - noting that config.element.entity becomes config.entity.
  • … but FINALLY, it’s easiest to template the icon in the tile card. :sunglasses:. Again noting that the templates here are running in context of forge so it is config.entity.

EDIT: Made this simpler by using the fact that since 6.2.0 you can set entity on uix-forge root config. While it was added to support auto-entities, it also means you can set a global entity and use config.entity everywhere, still taking note that in the element uix styling it is taking from the element context, but if you template entity in element then they will all be the same. I have updated the Forge documentation - UIX Forge - UI eXtension

Adjusted example still using --uix-icon but using uix styling on element not forge.

type: custom:uix-forge
forge:
  mold: card
  macros:
    icon_type:
      params:
        - entity_id
        - name: icon_on
          default: "'mdi:checkbox-outline'"
        - name: icon_off
          default: "'mdi:checkbox-blank-outline'"
      template: "{{ icon_on if is_state(entity_id, 'on') else icon_off }}"
element:
  type: tile
  entity: input_boolean.test_boolean
  name: Icon change in element
  uix:
    style:
      .: |
        :host {
          --uix-icon: {{ icon_type(config.entity) }};
        }

Template icon

type: custom:uix-forge
entity: input_boolean.test_boolean
forge:
  mold: card
  macros:
    icon_type:
      params:
        - entity_id
        - name: icon_on
          default: "'mdi:checkbox-outline'"
        - name: icon_off
          default: "'mdi:checkbox-blank-outline'"
      template: "{{ icon_on if is_state(entity_id, 'on') else icon_off }}"
element:
  type: tile
  entity: "{{ config.entity }}"
  name: Use entity in global config
  icon: "{{ icon_type(config.entity) }}"
1 Like

:bulb: UIX Forge documentation update :bulb:

The main UIX Forge documentation has been updated, specifically around using variables and macros, with a simplified approach to config.entity across Forge & Element config and UIX styling Note: To use config.entity in UIX styling of forge you need the latest 6.3.0 beta

1 Like