VO.
← Back to blog

A Spotify "now playing" card

Showing the track that's playing right now, or the last one played, with the Spotify Web API.

2 min read#spotify#api

The Spotify box on the home page shows what I'm listening to right now, or the last track I played when nothing is on. Instead of a third-party service it talks to the Spotify Web API directly.

One-time authorisation

Spotify needs my permission to read my account, so I do it once and keep a long-lived refresh token. A small helper script handles it: it starts a temporary server on 127.0.0.1:8888, prints the consent link and exchanges the returned code for a token. It only asks for two scopes: user-read-currently-playing and user-read-recently-played.

On the server

Each request swaps the refresh token for a short-lived access token, then tries two steps:

  1. /me/player/currently-playing: if a track is actually playing, return it.
  2. Otherwise /me/player/recently-played?limit=1: return the last track.

"Not playing" turned out to have more shapes than I expected: an empty response (204), an ad or a podcast (item: null), or paused playback. All of them fall through to step two. Any error returns null and the box switches to a quiet state; the page never breaks.

Secrets never reach the browser: it only calls the site's own /api/spotify. That response is cached for 30 seconds, so the number of calls to Spotify stays flat no matter how many visitors arrive.

return Response.json(nowPlaying, {
  headers: { "Cache-Control": "public, s-maxage=30, stale-while-revalidate=30" },
});

In the browser

The box asks again every 30 seconds. While a track plays, the progress bar advances locally every second, so it looks smooth without hitting the server each second. The box has a fixed size, so nothing shifts when data arrives.