Skip to content

Use authenticated brands proxy for repository icons#937

Open
manuveli wants to merge 1 commit intohacs:mainfrom
manuveli:fix/brands-proxy-repository-icons
Open

Use authenticated brands proxy for repository icons#937
manuveli wants to merge 1 commit intohacs:mainfrom
manuveli:fix/brands-proxy-repository-icons

Conversation

@manuveli
Copy link
Copy Markdown

@manuveli manuveli commented Apr 18, 2026

Summary

The HACS dashboard shows "icon not available" for custom integrations that ship inline brand assets (a feature introduced in Home Assistant 2026.3). Root cause is a combination of three things:

  • The homeassistant-frontend submodule is pinned to 3ffbd435 (2025-01-09) — pre-brands-proxy.
  • At that revision, brandsUrl({...}) still returns https://brands.home-assistant.io/_/{domain}/icon.png. That CDN no longer accepts new custom-integration submissions (see the brands-proxy API blog post), so custom-integration icons 404.
  • The dashboard passes useFallback: true — a parameter that has since been removed from upstream BrandsOptions, so a naive submodule bump breaks the TypeScript compile.

Changes

  1. Bump homeassistant-frontend submodule to current upstream master — brings in the new brands-url.ts that returns /api/brands/integration/{domain}/icon.png?token=…, along with fetchAndScheduleBrandsAccessToken / clearBrandsTokenRefresh exports.
  2. Remove useFallback: true from the brandsUrl({...}) call in src/dashboards/hacs-dashboard.ts — the field no longer exists on BrandsOptions. Fallback is now the HA backend's job (stale-while-revalidate through the proxy).
  3. Fetch and schedule the brands access token from the dashboard's bundle. Module-level _brandsAccessToken in brands-url.ts is bundle-scoped, so HACS must populate its own copy; upstream's fetchAndScheduleBrandsAccessToken silently swallows failures on older HA backends. Clear the refresh interval in disconnectedCallback to avoid leaking the setInterval when the panel unmounts.

Fixes hacs/integration#5171
Fixes hacs/integration#5223

A companion PR in the integration repo (hacs/integration) updates the HACS Update entity's entity_picture to use the same authenticated proxy path.

Test plan

  • script/bootstrap && script/build compiles clean (CI via .github/workflows/test.yml).
  • Against HA ≥ 2026.3 with HACS + a custom integration shipping brand/icon.png inline: downloads table shows real icons; rendered <img> has src=/api/brands/integration/{domain}/icon.png?token=….
  • Dark-mode toggle still flows through darkOptimized (filename prefixed with dark_).
  • Against HA < 2026.3 (no brands/access_token WS command): dashboard renders without thrown errors — fetchAndScheduleBrandsAccessToken catches silently.

🤖 Generated with Claude Code

The dashboard constructed icon URLs via the upstream `brandsUrl` helper
at a pinned submodule (3ffbd435, Jan 2025) that predates the
brands-proxy API introduced in HA 2026.3. After upstream rewrote
`brands-url.ts` to return `/api/brands/integration/{domain}/icon.png`
with an access token, custom integrations shipping inline brand assets
no longer render (the legacy CDN no longer accepts new custom
integration submissions).

Bump `homeassistant-frontend` to current master, drop the now-removed
`useFallback` parameter, and fetch/schedule the brands access token
from the dashboard's own bundle (module-level token state is
bundle-scoped, so HACS must populate its own copy). Clear the refresh
interval on disconnect.

Fixes hacs/integration#5171
Fixes hacs/integration#5223

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant