👨💻 Templates Engine (JavaScript & Jinja2)
NOTE
✨ Available on 💎 Pro & Ultimate Version Only
🌟 Overview
The Templates Engine provides a powerful way to manipulate and display data dynamically in your cards. It supports both JavaScript (local client-side evaluation) and a native, lightweight subset of Jinja2 (Home Assistant's native template syntax), allowing you to perform calculations, conditional formatting, and real-time state processing without external dependencies.
🚀 How to use it
Templates can be used in almost any card text or styling field (e.g., name, label, icon, background_color, icon_color, text_color).
You can choose between two syntax types depending on your needs:
Inside any template (JS or Jinja), you have instant access to the following Home Assistant objects:
entity: The main entity object assigned to the card.states: The state objects of all entities in your Home Assistant instance.hass: The full, global Home Assistant object.user: The current logged-in user object.
🟨 JavaScript Templates [[[ ... ]]]
Evaluates standard JavaScript code. It is fully synchronous and executed directly by the browser for maximum performance.
Example: Dynamic Icon based on State
Changes the icon dynamically based on whether the main entity is turned on or off.
type: "custom:material-template-card"
entity: "light.living_room"
icon: |
[[[
entity.state === "on" ? "mdi:lightbulb-on" : "mdi:lightbulb-off"
]]]Example: Advanced State Aggregation (Power Consumption)
Filters all light entities that expose a power attribute and sums them up in real-time.
type: "custom:material-template-card"
name: |
[[[
const totalPower = Object.values(states)
.filter(e => e.entity_id.startsWith("light.") && e.attributes.power)
.reduce((total, e) => total + e.attributes.power, 0);
return `Total Power: ${totalPower}W`;
]]]Example: Time-based Greeting
Displays a dynamic greeting based on the user's local browser time.
type: "custom:material-template-card"
name: |
[[[
const hours = new Date().getHours();
return "Good " + (hours < 12 ? "Morning" : (hours < 18 ? "Afternoon" : "Evening"));
]]]🟩 Jinja2 Templates {% ... %} & {{ ... }}
Provides a native, synchronous emulation of Home Assistant's server-side Jinja rendering engine. It handles standard HA functions and filters right inside the card.
Supported HA Functions & Filters:
states('domain.entity')is_state('domain.entity', 'value')state_attr('domain.entity', 'attribute')is_state_attr('domain.entity', 'attribute', 'value')- Filters:
| int,| float,| string - Statements:
{% if %},{% elif %},{% else %},{% endif %}
Example: Multi-line Conditional Block ({% if %})
Perfect for translating states or checking the status of secondary entities (like automations or scripts) with native YAML multiline blocks (|).
type: "custom:material-template-card"
entity: "automation.update_dns"
label: |
{% if is_state("automation.update_dns", "on") %}
Active
{% else %}
Disabled
{% endif %}Example: Multi-condition State Mapping ({% elif %})
Handles multiple states using the elif statement combined with numeric state type casting (| float).
type: "custom:material-template-card"
entity: "sensor.living_room_temperature"
label: |
{% if states('sensor.living_room_temperature') | float > 25.0 %}
Hot 🔥
{% elif states('sensor.living_room_temperature') | float < 18.0 %}
Cold ❄️
{% else %}
Comfortable 🛋️
{% endif %}Example: Inline Printing ({{ ... }})
A clean, single-line alternative for quick conditional outputs or attribute rendering.
type: "custom:material-template-card"
entity: "climate.living_room"
label: 'Preset: {{ state_attr("climate.living_room", "preset_mode") }}'🧩 Important Notes
WARNING
Jinja Loop Constraints: The native Jinja engine is highly optimized for synchronous UI rendering and speed. It does not support heavy server-side loop macros (like {% for state in states.light %}). For complex loops and heavy array manipulation, always use JavaScript Templates ([[[ ... ]]]).
NOTE
For more information on icon behaviors, check the using the icon property guide.
