Load integration icons through the Home Assistant brands proxy - #949
Open
ReikanYsora wants to merge 1 commit into
Open
Load integration icons through the Home Assistant brands proxy#949ReikanYsora wants to merge 1 commit into
ReikanYsora wants to merge 1 commit into
Conversation
Home Assistant 2026.3 moved brand images behind a local, token-gated proxy at /api/brands/. That proxy also serves the brand/ assets custom integrations now ship themselves, since home-assistant/brands stopped accepting images for custom integrations. The dashboard still built icon URLs against the public CDN through the pinned homeassistant-frontend, so every integration that is not grandfathered into the CDN rendered the placeholder image. Add a small brands-url helper mirroring the upstream module: resolve the brands access token over the WebSocket alongside the initial data, keep it fresh on the same 30 minute cadence core rotates it, and pick up a new one after a core restart. Integration icons are now requested from the proxy with that token, and the CDN URL remains the fallback on cores without the proxy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi :)
Proposed change
Since Home Assistant 2026.3, brand images are served by a local, token-gated proxy at
/api/brands/integration/{domain}/{image}(announcement). The proxy resolvescustom_components/<domain>/brand/first (core), which is what custom integrations rely on now thathome-assistant/brandsno longer accepts their images.The dashboard still builds icon URLs against the public CDN through the pinned
homeassistant-frontend(January 2025), so every integration that is not grandfathered into the CDN renders the placeholder, including integrations that are downloaded and whose icon core itself displays fine.This adds
src/tools/brands-url.ts, a port of the parts of upstreamsrc/util/brands-url.tsthat the pinned submodule predates, and wires it into the existing lifecycle:brands/access_token) in the samePromise.allashacs/infoandhacs/repositories/list, so the first render already has it and startup gains no extra round trip.hass.connectedcomes back after a core restart.brandsUrl()returns/api/brands/integration/{domain}/[dark_]icon.png?token=…. If no token could be obtained (core < 2026.3) it returns the exact CDN URL used today, so older cores see no change.hacs-dashboard.tsonly switches the import and dropsuseFallback, which the proxy implements itself.No submodule bump, no new dependency, no change to the
<img>markup.Scope
This fixes the icon for every integration that is downloaded, which is the case core's proxy is built for and the one reported in hacs/integration#5171, hacs/integration#5179, hacs/integration#5223 and hacs/integration#5402. Repositories that are not downloaded go through the proxy's CDN cache and behave exactly as today: grandfathered icons keep showing, the rest keep the placeholder.
That remaining gap is the one raised on #937 and can only be closed by a HACS-side endpoint such as hacs/integration#5388 / #945. This PR is deliberately independent of that work: the token plumbing here is what any such endpoint needs as well, and
brandsUrl()is the single place to redirect once it lands.Compared with #929 and #937: no
homeassistant-frontendbump, and the token is obtained and refreshed inside the HACS bundle, which is required because the upstream module's token is module-scoped and never populated from within a custom panel.Side effects
On cores with the proxy the HACS panel no longer contacts
brands.home-assistant.iofrom the browser, matching core's own behaviour since 2026.3.Release note
hacs/integrationpins the frontend release inscripts/install/frontend; a new frontend release and a pin bump are needed before this reaches users.Verification
tsc --noEmitreports no errors insrc/.gulp build-hacssucceeds on Node 18 (the CI version).script/bootstraponmaincurrently needs Skip tsparticles deps that break yarn resolve #943 to resolve dependencies.brand/icon.pngand are not inhome-assistant/brands:brands/access_tokenreturns the token,/api/brands/integration/{domain}/icon.png?token=…serves the real icon (200, 10.6 KB and 14 KB),dark_icon.pngfalls back to it, and the same request without a token is rejected with 403. The CDN URL used today answers 200 with the 3 KB placeholder for both domains, so no client-sideonerrorfallback could ever have caught this. The URL and token contract is the one core's frontend uses for the same images (connection-mixin.ts,brands-url.ts).Companion for the update entities: hacs/integration#5524.
Cheers ;)
ReikanYsora / Jérôme