Personal site built with Astro and deployed on Cloudflare Workers.
npm install
npm run devnpm run build
npm run previewnpm run check
npm run deploySet these secrets before deploying:
wrangler secret put NAVIDROME_BASE_URL
wrangler secret put NAVIDROME_USERNAME
wrangler secret put NAVIDROME_TOKEN
wrangler secret put NAVIDROME_SALTThis follows the Subsonic token flow (u, t, s).
Optional vars in wrangler.json:
NAVIDROME_CLIENT_NAME(default:learningis1.st)NAVIDROME_API_VERSION(default:1.16.1)
The widget fetches data from GET /api/now-playing.json.
It also uses GET /api/navidrome/cover-art/:id as an authenticated image proxy.
For setup/debugging, use GET /api/health/navidrome.json to validate Subsonic auth (u, t, s).
LAST_LISTENED_KV is also refreshed by a cron trigger (*/4 * * * *) so history continues updating even if nobody opens the site.
To enable "last listened" fallback, bind a KV namespace:
wrangler kv namespace create LAST_LISTENED_KV
wrangler kv namespace create LAST_LISTENED_KV --previewThen add the returned IDs to wrangler.json:
{
"kv_namespaces": [
{
"binding": "LAST_LISTENED_KV",
"id": "<production-namespace-id>",
"preview_id": "<preview-namespace-id>"
}
]
}Without KV, the endpoint still works but cannot return the last listened track when playback is idle.
Current payload from GET /api/now-playing.json includes:
source:playing,last_played, oridletrack: title/artist/album +coverArtUrlwhen availableprogress: playback percentage when currently playing
- Home page:
src/pages/index.astro - Base layout:
src/layouts/BaseLayout.astro - Global styles:
src/styles/global.css - Worker/deploy config:
wrangler.json
- Node.js
>=22