A personal music-collection site adds streaming platform links (Spotify, Apple Music, Bandcamp, etc.) to album pages by querying the MusicBrainz API. Because build-time queries would hit rate limits for 491 collection items, the data fetch happens client-side via a same-origin Astro API route, with results cached in memory for an hour. A custom web component progressively enhances a static list of Last.fm and Open Scrobbler links, appending the extra platform links only when JavaScript and the API call succeed, so the page still works without JS. The piece also briefly covers building near-identical Astro listing pages (like an all-time top 10) by filtering and sorting a content collection.

11m read timeFrom piccalil.li
Post cover image
Table of contents
A web component that talks to an API routeThe API routeThe web componentListing pagesSign up to get updates on open working projectsAndy Bell

Questions this post answers

How can I avoid hitting the MusicBrainz API rate limit when generating links for hundreds of items at build time?

Query the MusicBrainz API at request time instead of build time, using a per-visit fetch through a same-origin server API route rather than iterating every item during the build. Results can be cached in memory for an hour with a cache key based on artist and album to reduce repeated calls, avoiding the rate limiting MusicBrainz enforces on bulk build-time requests. Developers wiring third-party APIs into static sites can find similar rate-limit workarounds on daily.dev.

How do I build a web component that progressively enhances a static list of links using data from an API?

Render a static HTML list containing links that are always available (like Last.fm and Open Scrobbler), then define a custom element whose connectedCallback fetches additional data from an API route and appends new list items only if the fetch succeeds and returns data. This keeps the page functional without JavaScript while enhancing it when scripts and data are both available. Anyone shipping resilient, JS-optional UI patterns can track more progressive enhancement techniques on daily.dev.

Why should an internal Astro API route check the request origin before responding?

Checking that the request origin or referer matches the site's own origin prevents the endpoint from being used as an open public API, which matters because unrestricted endpoints attract unwanted traffic from bots, scrapers, and LLM-based agents. Returning a 403 for mismatched origins keeps the route usable only by the site's own web component. Teams hardening internal API routes against scraper and agent traffic can follow similar patterns via daily.dev.

2.3K Impressions