I really love what you've built, and I'm building a set of cards that are complimentary. I'd like to allow the users to import the styles they create with your button-builder. In order to make it easy for users to do that, my ask is to store then using Home Assistant's built-in frontend storage API that solves this with no custom backend endpoints — I use it in my own cards and it's been rock solid. How it works...
HA exposes a per-instance key/value store over the WebSocket connection, backed by .storage on the server.
Two scopes:
- system (frontend/{get,set,subscribe}_system_data) — shared across the whole instance/all users; admin-writable. Great for a shared library.
- user (frontend/{get,set,subscribe}_user_data) — per-HA-user.
No custom_components endpoint, no REST view — the frontend just calls it through the existing hass.connection. It persists server-side and survives restarts.
Read + live-subscribe:
const data = await hass.connection.sendMessagePromise({
type: 'frontend/get_system_data',
key: 'button_builder_library',
});
// live updates: fires immediately with the current value, then on every change (any device)
hass.connection.subscribeMessage(
(msg) => { applyLibrary(msg.value); },
{ type: 'frontend/subscribe_system_data', key: 'button_builder_library' }
);
Write:
await hass.connection.sendMessagePromise({
type: 'frontend/set_system_data',
key: 'button_builder_library',
value: {
button_builder_library: 1, // version field for future migrations
records: { // your saved designs, keyed by id/slug
'my-neon-tile': { name: 'Neon Tile', folder: 'Tiles', tags: ['neon'],
updatedAt: 1732600000000, yaml: '…', config: { /* structured */ } },
},
},
});
value is any JSON-serializable object — keep your existing record shape ({id,name,folder,tags,updatedAt,yaml}) and just nest it under a versioned envelope.
How I use it... each of my cards keeps its library under its own namespaced key (e.g. ltek_button_styles), stores { : 1, presets: { : {...} } }, and subscribes so an edit on one dashboard re-renders every card on the instance instantly. A one-time migration copies any legacy localStorage entries up into the system store on first load, then reads from the store thereafter — so existing users lose nothing.
Why it's worth it for Button Builder:
- Designs sync across devices/sessions/browsers automatically.
- No backend work; it rides the WebSocket you already have.
- It opens the door for other cards to read a shared library (I'm about to post major revamp-releases of two cards which could leverage Button Builder designs if they were readable this way).
Happy to share the exact migration snippet I use (localStorage → system_data, once) if helpful.
I really love what you've built, and I'm building a set of cards that are complimentary. I'd like to allow the users to import the styles they create with your button-builder. In order to make it easy for users to do that, my ask is to store then using Home Assistant's built-in frontend storage API that solves this with no custom backend endpoints — I use it in my own cards and it's been rock solid. How it works...
HA exposes a per-instance key/value store over the WebSocket connection, backed by .storage on the server.
Two scopes:
No custom_components endpoint, no REST view — the frontend just calls it through the existing hass.connection. It persists server-side and survives restarts.
Read + live-subscribe:
Write:
value is any JSON-serializable object — keep your existing record shape ({id,name,folder,tags,updatedAt,yaml}) and just nest it under a versioned envelope.
How I use it... each of my cards keeps its library under its own namespaced key (e.g. ltek_button_styles), stores { : 1, presets: { : {...} } }, and subscribes so an edit on one dashboard re-renders every card on the instance instantly. A one-time migration copies any legacy localStorage entries up into the system store on first load, then reads from the store thereafter — so existing users lose nothing.
Why it's worth it for Button Builder:
Happy to share the exact migration snippet I use (localStorage → system_data, once) if helpful.