← Back to archive

Repo of the Day

bryanhamiltondev/dj-card-preview

Published: Oct 4, 2026

Open repository ↗

The hover preview from The DJ Calendar: a 30-second iTunes audio preview, an 8-bar EQ driven by the real audio frequencies via Web Audio, and a consent-first contract for touch, reduced motion, and conflicts. Zero dependencies

Summary

dj-card-preview is a zero-dependency, vanilla JavaScript widget that turns an artist card on hover into a 30-second iTunes audio preview backed by a real Web Audio equalizer. It was extracted from The DJ Calendar, where 99 homepage cards run the same code, and it is built to fail gracefully on touch, with reduced motion, or when no preview exists.

What it is useful for

  • Adding hover-to-play sample previews to artist directories, podcast lists, or any grid of audio links without pulling in a framework
  • Driving a canvas EQ from actual frequency data, not a decorative loop: an AnalyserNode with fftSize 64 and smoothing 0.8 feeds eight bars, one per frequency bin
  • Building a card grid that respects accessibility constraints (touch, reduced motion) without writing the conditional logic yourself
  • Letting a fallback iTunes Search API lookup handle cards that arrive without a cached preview URL

How engineers can use it

Markup: Each card is an anchor with class dj-card and data attributes data-id, data-name, data-image, plus optional data-preview-url and data-preview-title for caching. A waveform-canvas sized 280x40 sits inside a card-image-overlay that holds the "You are now listening to" label and track name. The README includes a full David Guetta example.

Container: Place cards in #djGrid or any element matching .genre-artists-grid.

Lookup path: If data-preview-url is missing, the widget calls the iTunes Search API (entity=musicTrack, limit 12), picks the first result with a preview, and writes the URL back to the card. If no result is found, the card is marked data-preview-miss and silently skipped on future hovers, avoiding repeated failed lookups.

State handling: A generation counter on each card (_djcPreviewGen) invalidates stale callbacks when the cursor leaves mid-load. Touch devices (matched by hover: none, pointer: coarse) get a tap-to-toggle gesture that doubles as the user gesture browsers require before audio. prefers-reduced-motion: reduce disables previews entirely, and the widget stands down if a site-wide favorites player is already running.

Extras: While a preview plays, the document title becomes Artist - Track, and navigator.mediaSession receives metadata for OS-level media keys. The audio element is set to crossOrigin: anonymous, which is what allows the analyser to read frequencies from cross-origin iTunes preview files.

Setup: The README documents no install commands. It states "No build step, no framework, no dependencies" and links a live demo that hardcodes one cached preview URL (David Guetta, "Titanium (feat. Sia)") so it works with no backend. Documented limitation: the browser autoplay policy means the demo requires a click on the page before hover audio will play; on touch, the tap itself satisfies the gesture. Requirements are "any browser from the last decade with Web Audio support."