---
key: api.artwork-rooted-urls
title: '2026-07-07 — API artwork contract: rooted URLs produced server-side'
status: active
since: '2026-07-07'
supersedes: none
superseded-by: none
rule: API response DTOs return artwork as rooted, directly-usable URLs (plus passthrough for absolute/proxy URLs), never relative Blazor-convention paths.
signals: 'no SPA `<base href>`, `ApiArtwork` helper · paths: `ErsatzTV.Core/Api/ApiArtwork.cs`, `ErsatzTV.Application/LibraryBrowse/Queries/GetLibraryBrowseItemsHandler.cs` · issues: none cited (PR #181, PR #183)'
mechanics: '`ErsatzTV.Core/Api/ApiArtwork.cs`'
---

API response DTOs return artwork as rooted, directly-usable URLs (`/artwork/posters/...`,
`/artwork/thumbnails/...`, `/artwork/fanart/...`), plus passthrough for absolute `http(s)://` URLs
and Jellyfin/Emby proxy variants. Established by PR #181
(`ErsatzTV.Application/LibraryBrowse/Queries/GetLibraryBrowseItemsHandler.cs`, private `Artwork(...)`
helper — comment: *"Returns a rooted, directly-usable artwork URL for the SPA's `<img src>`... the
SPA [needs it pre-rooted]"*), then generalized into the reusable `ApiArtwork` helper
(`ErsatzTV.Core/Api/ApiArtwork.cs`, PR #183). Root cause: the SPA has no `<base href>`, unlike
Blazor, so relative artwork paths that worked for Blazor pages 404 in the SPA. Do **not** reuse the
Application-layer Mappers used by Blazor (e.g. `MediaCards`/`Television` mappers) for new API
DTOs — those still return old Blazor-convention relative paths; map from the domain/VM directly and
root the path via `ApiArtwork`.
