Symptoms
When integrating the Napster Companion Web SDK in a Next.js (or similar React-based) application, the agent connects successfully on first load but fails on every subsequent reload. Errors appear in the browser console referencing a WebSocket connection failure.
Root cause
Napster session tokens are single-use and short-lived. If your application fetches a token once (e.g. at build time, or stores it in a JSON file or environment variable) and reuses it across multiple sessions or page reloads, the token will be stale by the time it is used again, causing the WebSocket handshake to fail.
This commonly happens when a token is hardcoded into a config, cached in state that persists across hot-reloads, or generated once server-side and embedded as a static prop.
Resolution
Generate a fresh token on every page load by calling the token endpoint at runtime, immediately before initialising the SDK. Never store or reuse tokens between sessions.
useEffect (React) or equivalent lifecycle hook that runs on mount — not in a shared module-level variable, not in getStaticProps, and not in local storage.Step-by-step fix
- Locate where your application retrieves the session token. If it is stored in a variable, file, or static prop, that is the source of the problem.
- Move the token fetch call into your component's mount lifecycle (e.g. inside
useEffect(() = { ... }, [])in React oronMountedin Vue). - Pass the freshly fetched token directly into
NapsterCompanionApiSdk.init({ token, ... })without storing it anywhere between calls. - Ensure your cleanup function (the return value of
useEffect) destroys the SDK instance so the next mount starts cleanly. - Reload the page twice to confirm the agent initialises successfully on both loads.
Additional notes
This issue is not specific to Next.js — any framework that caches module-level state across hot-reloads (Vite, Remix, etc.) can exhibit the same behaviour. The fix is the same: treat the token as a one-time credential that must be obtained fresh for every SDK initialisation.