A Home Assistant custom component for loading and displaying custom SVG icons from your local filesystem. Perfect for adding organization-specific, branded, or personalized icons to your Home Assistant UI.
Use the Gallery card to display your local icons
- 🔍 Icon picker integration for UI selection
- 📂 Load SVG icons from a configurable local folder
- 🔄 Automatic icon discovery
- ⚡ Optimized frontend rendering
- 🛡 Secure SVG parsing
or:
- Open HACS in your Home Assistant instance
- Click on "Custom repositories"
- Add
https://github.com/Mariusthvdb/custom_local_iconsas a custom repository with category "Integration" - Search for "Custom Local Icons" and click Install
- Restart Home Assistant
- Download the latest release
- Copy the
custom_local_iconsfolder to your Home Assistantcustom_componentsdirectory:/config/custom_components/custom_local_icons - Restart Home Assistant
or:
- Go to Settings → Devices & Services
- Click Add Integration (or search for "Custom Local Icons")
- Select "Custom Local Icons"
- Enter your icon folder path (default:
www/custom_local_icons) - Click Create Entry
The folder can later be changed through the integration's Options menu.
Create your icon folder in your Home Assistant config directory:
/config/www/custom_local_icons/
├── icon1.svg
├── icon2.svg
├── subfolder/
│ ├── icon3.svg
│ └── icon4.svg
Use the prefix cli: followed by your icon name:
cli:icon_name
cli:subfolder/icon_name
lovelace:
dashboards:
ui-cctv:
mode: yaml
filename: ui-cctv.yaml
title: Cameras
icon: cli:home-videoon the most versatile card of all, custom:button-card
type: custom:button-card
icon: >
[[[ return states['binary_sensor.rook_co_lekkage'].state === 'off'
? 'cli:home-check' : 'mdi:home-alert'; ]]]
in a stock entities card:
type: entities
title: Custom local icons
entities:
- entity: switch.light
name: Light switch
icon: cli:light-switch
or eg in a glance card with UIX templates
type: glance
entities:
- entity: device_tracker.philips_hue_1
style: |
:host {
--uix-icon:
{% set con = states(config.entity) %}
cli:hue-bridge-v2{{'-off' if con == 'not_home'}};
}
When icons are added, removed, or modified in the filesystem, the changes are not automatically reflected in an active Home Assistant session. To apply updates, use one of the following methods:
Reload the Home Assistant browser tab. This ensures the icon list and frontend cache are fully re-initialized.
No Home Assistant restart or integration reload is required.
If your setup includes UIX support, you can use the clear_cache action:
action: fire-dom-event
uix:
action: clear_cacheIn a badge:
This clears the frontend cache, causing the icon list to be requested again.
entity: input_select.theme
show_name: true
show_state: false
icon: mdi:broom
name: Clear Frontend Cache
tap_action: none
hold_action:
action: fire-dom-event
uix:
action: clear_cacheThe backend always reflects the latest filesystem state when /list is requested. The frontend caches icons for performance and does not continuously poll for changes. Icon updates are therefore only visible after a view reload or cache clear action.
-
Frontend caching Icons are cached in memory after first load for instant reuse.
-
Loading strategy Icons load asynchronously and render with a safe fallback until available. Frequently used icons are preloaded after initial list retrieval.
Your SVG files should follow these guidelines:
- Valid SVG Format - Must be valid XML
- Viewbox Attribute - Used as-is when present. If missing or empty, defaults to 0 0 24 24
- Path Elements - Use
<path>elements for icon shapes - No Scripts - Embedded
<script>tags are blocked for security - No Event Handlers - Event handlers (
onclick,onload, etc.) are blocked - Safe Content - Only path data is extracted and rendered
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#44739e">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/>
</svg>SVG content is validated before rendering:
- Blocks
<script>elements - Blocks inline event handlers (
on*) - Requires valid SVG structure
- Extracts only path data for rendering
- No real-time updates (reload required)
- SVG format only
- Large icon sets may increase initial load time
- Icons must be stored in the configured folder
- Invalid or unsupported icons may appear in the icon list but will not render
Custom Local Icons provides lightweight logging in both backend and frontend.
- file access
- API responses
- integration-level issues
If icons are not loading as expected, enable Frontend debug logging in the integration options and open your browser developer console.
Additional information will be displayed, including:
- Integration metadata
- Icon count
- Icon list endpoint
- Integration info endpoint
- SVG viewBox deviations
- Icon loading diagnostics
When disabled:
- only warnings/errors are shown
Logging is for debugging only and does not reflect final render behavior.
Check:
- file is in correct folder
- valid filename (no spaces)
- /list endpoint includes it
Common causes:
- Complex SVG features (transforms, masks, filters, grouped elements) may render differently because only geometry is extracted.
- complex editor exports (Inkscape / Illustrator)
- missing or unusual viewBox (usually non-fatal)
Note: Icons may preview correctly in file managers, but frontend rendering depends on simplified SVG path extraction.
Allowed: a-z A-Z 0-9 _ - /
Not allowed:
- spaces
- special characters
To view all icons currently detected by the integration, open:
http://<home-assistant>/custom_local_icons/list
The
/custom_local_icons/listendpoint is provided by the integration and is independent of the configured icon folder.
Example response:
[
{ "name": "home" },
{ "name": "light-switch" },
{ "name": "devices/sensor" }
]Icons can then be referenced as:
icon: cli:home
icon: cli:light-switch
icon: cli:devices/sensor- Icon names can only contain alphanumeric characters, underscores, hyphens, and forward slashes
- Icon names containing spaces are not supported
- Example valid names:
my_icon,icon-1,folder/icon
- Check that the SVG file exists in the configured folder
- Verify file permissions (Home Assistant must be able to read the file)
- Your SVG contains embedded JavaScript or event handlers
- Remove these elements from your SVG file
Invalid or unsupported icons may appear in the backend icon /list but will not render in the frontend icon picker or view; a warning is logged in the browser console.
In other words:
The icon list reflects filesystem discovery and may include icons that fail validation or rendering at runtime.
This system intentionally separates:
- discovery (backend)
- rendering (frontend)
- validation (runtime best-effort) This avoids blocking icons from appearing while still protecting rendering stability.
Contributions are welcome! Please feel free to submit issues or pull requests.
See the LICENSE file for details.
For issues, questions, or feature requests, please open an issue on GitHub.
See CHANGELOG.md for release history and version information.
Custom Local Icons - Making Home Assistant icons personal and secure. 🚀
