[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81060":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":14,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":27,"readmeContent":28,"aiSummary":29,"trendingCount":15,"starSnapshotCount":15,"syncStatus":14,"lastSyncTime":30,"discoverSource":31},81060,"ha-linked-cards","rusty4444\u002Fha-linked-cards","rusty4444","Shared storage-backed reusable dashboard card templates for Home Assistant",null,"JavaScript",51,1,49,2,0,41.1,"MIT License",false,"main",true,[22,23,24,25,26],"custom-card","dashboard","hacs","home-assistant","lovelace","2026-06-12 04:01:31","# Linked Cards for Home Assistant\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fbuymeacoffee.com\u002Frusty4\" target=\"_blank\">\n    \u003Cimg src=\"https:\u002F\u002Fcdn.buymeacoffee.com\u002Fbuttons\u002Fv2\u002Fdefault-yellow.png\" alt=\"Buy Me A Coffee\" height=\"50\">\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\n\nReusable, storage-backed dashboard cards for Home Assistant UI-mode dashboards.\n\nLinked Cards fills the gap between Home Assistant's friendly visual dashboard editor and YAML-only reuse tools such as `decluttering-card`. Define a **master card template** once, then place lightweight linked instances anywhere. When the master template changes, every linked instance renders the new card configuration after refresh.\n\n![Linked Cards overview](docs\u002Fscreenshots\u002Flinked-cards-overview.svg)\n\n## Why this exists\n\nHome Assistant users often maintain several dashboards: wall tablet, phone, admin, energy, room-specific views, guest views. The same room card, security card, navigation card, or status stack is copied repeatedly. Today that means:\n\n- edit the same card YAML in multiple places;\n- risk inconsistent versions across dashboards;\n- use YAML-heavy `decluttering-card` \u002F `streamline-card`; or\n- give up the UI dashboard editor.\n\nCommunity requests repeatedly ask for native \"master card\", \"linked card\", or \"reusable card\" support in UI mode. This project is a practical HACS-friendly implementation of that missing layer.\n\n## What it provides\n\n- `custom:linked-card` — renders a stored master card by template id, or renders cards directly from another dashboard\u002Fview.\n- `custom:linked-section` — renders a stored master section (title + card grid) by template id.\n- `linked-card-manager` — now creates and edits both card and section templates from the Home Assistant UI.\n- Visual editor support for `custom:linked-card` instances: template picker, variable overrides, source-dashboard mode, and inline\u002Fpopup display.\n- Source-dashboard mode compatible with Global-cards-style workflows: maintain pop-ups, headers, or shared UI on a source dashboard and reuse them elsewhere.\n- Home Assistant custom integration storage under `.storage\u002Flinked_cards.templates`.\n- Safe variable substitution using `${variable}` placeholders.\n- Any Lovelace card can be the child card: tile, grid, entities, custom cards, Bubble Card pop-ups, etc.\n- Live template update events: saved\u002Fdeleted templates re-render affected linked-card instances without waiting for a full dashboard refresh.\n- Template export\u002Fimport from the manager card.\n- Static JS resource served by the integration at `\u002Flinked-cards\u002Flinked-card.js`.\n- REST API for advanced users and future UI tooling.\n\n## Installation\n\n### HACS custom repository\n\n1. HACS → Integrations → ⋮ → Custom repositories.\n2. Add this repository URL.\n3. Category: **Integration**.\n4. Install **Linked Cards**.\n5. Restart Home Assistant.\n6. Go to **Settings → Devices & services → Add integration** and add **Linked Cards**.\n7. Add the frontend resource:\n\n```yaml\nurl: \u002Flinked-cards\u002Flinked-card.js\ntype: module\n```\n\nOr add it from **Settings → Dashboards → Resources**.\n\n### Manual install\n\nCopy this folder into Home Assistant:\n\n```text\ncustom_components\u002Flinked_cards\n```\n\nRestart Home Assistant, add **Linked Cards** from **Settings → Devices & services**, then add the resource:\n\n```text\n\u002Flinked-cards\u002Flinked-card.js\n```\n\n## Quick start\n\n### 1. Add a manager card to an admin-only dashboard\n\n```yaml\ntype: custom:linked-card-manager\ntemplate: room-summary\n```\n\nPaste and save this master template:\n\n```json\n{\n  \"description\": \"Reusable room summary grid with a light and climate tile.\",\n  \"variables\": {\n    \"area\": \"Living Room\",\n    \"light\": \"light.living_room\",\n    \"climate\": \"climate.living_room\"\n  },\n  \"card\": {\n    \"type\": \"grid\",\n    \"title\": \"${area}\",\n    \"columns\": 2,\n    \"square\": false,\n    \"cards\": [\n      {\n        \"type\": \"tile\",\n        \"entity\": \"${light}\",\n        \"name\": \"Lights\",\n        \"features\": [{ \"type\": \"light-brightness\" }]\n      },\n      {\n        \"type\": \"tile\",\n        \"entity\": \"${climate}\",\n        \"name\": \"Climate\",\n        \"features\": [{ \"type\": \"target-temperature\" }]\n      }\n    ]\n  }\n}\n```\n\n### 2. Place linked instances anywhere\n\nUse the Home Assistant visual editor when adding `custom:linked-card`. The editor lets you select **Template** mode, choose a stored template, and enter variable overrides as JSON.\n\nLiving room:\n\n```yaml\ntype: custom:linked-card\ntemplate: room-summary\nvariables:\n  area: Living Room\n  light: light.living_room\n  climate: climate.living_room\n```\n\nBedroom:\n\n```yaml\ntype: custom:linked-card\ntemplate: room-summary\nvariables:\n  area: Bedroom\n  light: light.bedroom\n  climate: climate.bedroom\n```\n\nKitchen with a fallback if the template is missing:\n\n```yaml\ntype: custom:linked-card\ntemplate: room-summary\nvariables:\n  area: Kitchen\n  light: light.kitchen\n  climate: climate.kitchen\nfallback:\n  type: markdown\n  content: Linked card template is not available.\n```\n\n## Source-dashboard mode\n\nSource-dashboard mode lets you maintain shared cards on a normal Home Assistant dashboard and render them elsewhere. This is useful for Global-cards-style workflows such as Bubble Card pop-ups, shared headers, and reusable navigation sections.\n\nCreate a source dashboard, for example `global-cards`, then add the cards you want to reuse with Home Assistant's normal visual editor.\n\n### Inline shared cards\n\n```yaml\ntype: custom:linked-card\nmode: source\nsource_dashboard: global-cards\nsource_view: header\nsource_display: inline\n```\n\n- `source_dashboard` is the dashboard `url_path`.\n- `source_view` is optional and can be a view path or view title. Omit it to load all views.\n- `source_display: inline` renders the cards in place.\n- Sections views are supported; card `grid_options.columns` are respected in a 12-column grid fallback.\n\n### Popup\u002Finvisible source cards\n\n```yaml\ntype: custom:linked-card\nmode: source\nsource_dashboard: global-cards\nsource_view: popups\nsource_display: popup\n```\n\n`source_display: popup` mounts the source cards invisibly under the Lovelace root in normal view mode. In edit mode, the card shows a status panel with the dashboard, view, display mode, and loaded card count.\n\nThis pattern works well for Bubble Card pop-ups defined once on a source dashboard and opened from buttons on other dashboards.\n\n## Linked Sections\n\nJust as linked cards let you define a master card once and reuse it everywhere, linked sections let you define a reusable **section** (title + grid of cards) as a stored template and place it on any dashboard with `custom:linked-section`.\n\nA section template stores a `title` and an array of `cards`, along with optional `grid_options.columns` to control default column sizing. Variables let you parameterise entity IDs, titles, and any other card field.\n\n### Create a section template\n\nUse the manager card and select **Section template** to save a master section:\n\n```json\n{\n  \"description\": \"Reusable room controls section with lights and climate.\",\n  \"variables\": {\n    \"area\": \"Living Room\",\n    \"light\": \"light.living_room\",\n    \"climate\": \"climate.living_room\"\n  },\n  \"section\": {\n    \"title\": \"${area} Controls\",\n    \"grid_options\": { \"columns\": 2 },\n    \"cards\": [\n      {\n        \"type\": \"tile\",\n        \"entity\": \"${light}\",\n        \"name\": \"Lights\",\n        \"features\": [{ \"type\": \"light-brightness\" }]\n      },\n      {\n        \"type\": \"tile\",\n        \"entity\": \"${climate}\",\n        \"name\": \"Climate\",\n        \"features\": [{ \"type\": \"target-temperature\" }]\n      }\n    ]\n  }\n}\n```\n\n### Place a linked section\n\n```yaml\ntype: custom:linked-section\ntemplate: room-controls\nvariables:\n  area: Living Room\n  light: light.living_room\n  climate: climate.living_room\n```\n\nFor the office:\n\n```yaml\ntype: custom:linked-section\ntemplate: room-controls\nvariables:\n  area: Office\n  light: light.office\n  climate: climate.office\n```\n\nThe section renders with the given title and cards, all laid out in a responsive grid. Edit the master template once; refresh dashboards and all uses show the new configuration.\n\n### Section schema\n\n| Field | Required | Type | Description |\n|-------|----------|------|-------------|\n| `title` | Yes | string | Section heading. Supports `${variable}` substitution. |\n| `cards` | Yes | array | Array of Lovelace card configs. |\n| `grid_options.columns` | No | number | Default column count used to size cards that don’t set their own `grid_options.columns`. |\n\n\n## Template format\n\n```json\n{\n  \"description\": \"Optional human-readable notes.\",\n  \"variables\": {\n    \"default_name\": \"Default values are optional\"\n  },\n  \"card\": {\n    \"type\": \"tile\",\n    \"entity\": \"${entity}\",\n    \"name\": \"${name}\"\n  }\n}\n```\n\nRules:\n\n- `card` is required and must be a Lovelace card object.\n- `variables` is optional and supplies defaults.\n- Instance variables override template defaults.\n- Placeholders work in strings and object keys: `${area}`, `${entity}`, `${nested.value}`.\n- Missing variables render as an empty string so a broken template is visible rather than silently using stale values.\n- Template ids may contain letters, numbers, `.`, `_`, and `-` only.\n\n## Manager export\u002Fimport\n\nThe `custom:linked-card-manager` card can:\n\n- save and delete stored templates;\n- export the selected template as JSON;\n- export all templates as a JSON archive;\n- import a template JSON file and save it back to Home Assistant storage.\n\nImported files may use either of these shapes:\n\n```json\n{ \"template_id\": \"room-summary\", \"template\": { \"card\": { \"type\": \"tile\", \"entity\": \"light.example\" } } }\n```\n\nor a raw template payload:\n\n```json\n{ \"variables\": {}, \"card\": { \"type\": \"tile\", \"entity\": \"light.example\" } }\n```\n\n## API\n\nAll endpoints require normal Home Assistant authentication.\n\n### List templates\n\n```http\nGET \u002Fapi\u002Flinked_cards\u002Ftemplates\n```\n\nResponse:\n\n```json\n{\n  \"templates\": {\n    \"room-summary\": {\n      \"variables\": {},\n      \"card\": { \"type\": \"tile\", \"entity\": \"light.example\" }\n    }\n  }\n}\n```\n\n### Save template\n\n```http\nPOST \u002Fapi\u002Flinked_cards\u002Ftemplates\u002Froom-summary\nContent-Type: application\u002Fjson\n\n{\n  \"variables\": { \"entity\": \"light.example\" },\n  \"card\": { \"type\": \"tile\", \"entity\": \"${entity}\" }\n}\n```\n\n### Delete template\n\n```http\nDELETE \u002Fapi\u002Flinked_cards\u002Ftemplates\u002Froom-summary\n```\n\n### Live update event\n\nWhen a template is saved or deleted, the integration fires a Home Assistant event:\n\n```text\nlinked_cards_template_updated\n```\n\nEvent data:\n\n```json\n{ \"template_id\": \"room-summary\", \"action\": \"saved\" }\n```\n\nOpen linked-card instances subscribe to this event, invalidate the affected cache entry, and re-render matching template-based cards.\n\n## Example patterns\n\n### Shared navigation card\n\nCreate one navigation grid and reuse it on every dashboard. Update paths\u002Ficons once.\n\n```json\n{\n  \"card\": {\n    \"type\": \"grid\",\n    \"columns\": 4,\n    \"square\": false,\n    \"cards\": [\n      { \"type\": \"button\", \"name\": \"Home\", \"icon\": \"mdi:home\", \"tap_action\": { \"action\": \"navigate\", \"navigation_path\": \"\u002Flovelace\u002Fhome\" } },\n      { \"type\": \"button\", \"name\": \"Lights\", \"icon\": \"mdi:lightbulb\", \"tap_action\": { \"action\": \"navigate\", \"navigation_path\": \"\u002Flovelace\u002Flights\" } },\n      { \"type\": \"button\", \"name\": \"Energy\", \"icon\": \"mdi:lightning-bolt\", \"tap_action\": { \"action\": \"navigate\", \"navigation_path\": \"\u002Fenergy\" } },\n      { \"type\": \"button\", \"name\": \"Security\", \"icon\": \"mdi:shield-home\", \"tap_action\": { \"action\": \"navigate\", \"navigation_path\": \"\u002Flovelace\u002Fsecurity\" } }\n    ]\n  }\n}\n```\n\n### Shared device-status card\n\nUse one template for routers, servers, NAS devices, or 3D printers.\n\n```json\n{\n  \"variables\": {\n    \"name\": \"Device\",\n    \"power\": \"sensor.device_power\",\n    \"status\": \"binary_sensor.device_online\"\n  },\n  \"card\": {\n    \"type\": \"entities\",\n    \"title\": \"${name}\",\n    \"entities\": [\"${status}\", \"${power}\"]\n  }\n}\n```\n\n## Security and privacy\n\n- Templates are stored locally in Home Assistant storage.\n- The integration does not call external services.\n- Normal Home Assistant auth protects the API.\n- Template reads are available to authenticated users so linked cards can render.\n- Template create\u002Fupdate\u002Fdelete actions require a Home Assistant administrator account.\n- Template ids, size, nesting depth, count, and top-level shape (`card` or `section`) are validated server-side.\n- Do not store secrets in card templates. Treat template JSON like dashboard YAML.\n\n## Limitations\n\n- Source-dashboard mode reads Lovelace dashboard config through the frontend connection; the source dashboard must be accessible to the current user.\n- Source-dashboard configs are cached in the browser for 60 seconds.\n- The manager's template body remains JSON so any Lovelace\u002Fcustom card can be represented exactly. Use source-dashboard mode when you want to author the shared card itself with Home Assistant's native visual editor.\n- Variables are string interpolation, not arbitrary JavaScript or Jinja. This is intentional for safety and portability.\n- Cross-dashboard use works because templates are stored globally by the integration, not inside a single dashboard config.\n\n## Roadmap\n\n- [x] Visual template picker\u002Feditor for linked-card instances.\n- [x] Visual template picker\u002Feditor for linked-section instances.\n- [x] Source-dashboard mode for Global-cards-style reusable pop-ups\u002Fheaders.\n- [x] Live update event after saving\u002Fdeleting a template.\n- [x] Template export\u002Fimport.\n- [ ] Import duplicated existing dashboard cards as stored templates.\n- [ ] Per-template usage search across dashboards.\n- [ ] Optional variable schema so instances get a richer generated UI form.\n\n## Development\n\n```bash\nnpm install\nnpm test\nnpm run build\n```\n\nBuild output is copied to:\n\n```text\ncustom_components\u002Flinked_cards\u002Fwww\u002Flinked-card.js\n```\n\n## Validation performed\n\n- Vitest unit tests for template id validation, recursive variable rendering, default\u002Foverride behaviour, source-dashboard structure extraction, editor wiring, live event wiring, and package layout.\n- ESBuild bundle generation.\n- Python syntax compilation for the Home Assistant custom component.\n- README verified for v0.2.0 feature coverage: source-dashboard mode, visual editor, live events, export\u002Fimport, and updated roadmap.\n\nThis project was developed with the assistance of AI tools.\n\n## License\n\nMIT\n","该项目为Home Assistant提供了一种基于共享存储的可重用仪表盘卡片模板。其核心功能是允许用户定义一个主卡片模板，然后在多个地方放置轻量级的链接实例，当主模板更新时，所有链接实例会在刷新后自动呈现新的配置。技术特点包括支持通过`custom:linked-card`和`custom:linked-section`渲染存储的卡片或部分，以及通过`linked-card-manager`从HomeAssistant界面创建和编辑这些模板。此外，它还支持变量替换、实时模板更新事件及REST API等高级特性。此项目特别适合那些需要维护多个不同用途（如墙面平板、手机、管理后台等）仪表盘的家庭自动化爱好者使用，帮助他们减少重复工作并保持一致性。","2026-06-11 04:03:21","CREATED_QUERY"]