Skip to content

feat: Last.fm / Spotify "now playing" widget #30

Description

@KotaHusky

Summary

Add a "now playing" music widget that shows the track currently being listened to (or the most recently scrobbled track) via the Last.fm public API. This is a popular personal-page widget that adds personality and real-time character to the hub — fitting given the 🎧 emoji already in the hobby row.

Inspiration

  • theodorusclarence.com's Spotify now-playing post is a widely-cited implementation guide
  • Compiled Thoughts blog documents a Last.fm-only approach (no OAuth required — just a public API key)
  • Bento.me supports music embeds as first-class blocks
  • Multiple personal dev portfolios use this pattern as a "living" element

Why Last.fm over Spotify directly

Last.fm's user.getrecenttracks endpoint is a simple GET request with only a public API key — no OAuth, no refresh tokens, no secrets beyond an API key stored in an env var. Spotify's Web API requires client credentials and token refresh, which adds significant infra. Last.fm also scrobbles from Spotify automatically if the accounts are linked.

Proposed Behavior

  • A small widget card below the hobby emoji row
  • Shows album art thumbnail, track title, and artist name
  • If a track is currently playing: shows a subtle animated equalizer icon
  • If no track is currently playing: shows "last played: " with a timestamp
  • Fetches via a Next.js API route (/api/now-playing) to keep the API key server-side
  • Polling or ISR revalidation (e.g. every 30 seconds)

Acceptance Criteria

  • /api/now-playing route fetches from Last.fm user.getrecenttracks with limit=1
  • NowPlayingWidget component renders track name, artist, and album art
  • "Now playing" vs "Last played" state is differentiated visually
  • Last.fm API key stored in LASTFM_API_KEY env var (server-side only, not NEXT_PUBLIC_)
  • Graceful fallback if the API is unavailable or the user has no recent tracks
  • Widget has a unit test with a mocked API response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeatureNew distinct feature

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions