javascriptreactjsspotifydynamic-script-loading

Using Spotify Web Playback SDK with React


Spotify has a new feature in beta supporting full song playback in browser, Web Playback SDK. The documentation shows an example of immediately initializing a player using script tags in the main HTML file. This requires an access token to be set immediately in the script. My issue is that I am creating a React app and I only want to initialize a player if a user clicks a button to login to their Spotify account. In order to load in a script only once this event occurs, I am using react-load-script. The flow I want is: a user clicks a button to login to their Spotify account, once their login is authenticated by Spotify my app receives an access token, the web playback script is then loaded, once the script is loaded a callback function is called and the player is initialized using the access token.

The problem is that the Spotify object does not exist until the spotify-player script has been loaded in. When the handleScriptLoad callback is actually invoked, the Spotify object is defined, but when the code is being compiled, it is not. Does anyone have any ideas how to get around this problem?

Code sample from the relevant React component:

import Script from 'react-load-script'

...

handleScriptLoad = () => {
const token = this.props.tokens.access
const player = new Spotify.Player({      // Spotify is not defined until 
  name: 'Spotify Web Player',            // the script is loaded in 
  getOAuthToken: cb => { cb(token) }
})

player.connect()
}

...

in my React component's render method:

<Script 
  url="https://sdk.scdn.co/spotify-player.js" 
  onError={this.handleScriptError} 
  onLoad={this.handleScriptLoad}
/>

Solution

  • In theory, it is possible.

    The Web Playback SDK will asynchronously load the window.Spotify object in our SDK via an external script. So, waiting for the object to be defined should solve the problem:

    handleScriptLoad = () => {
      return new Promise(resolve => {
        if (window.Spotify) {
          resolve();
        } else {
          window.onSpotifyWebPlaybackSDKReady = resolve;
        }
      });
    }
    

    That should solve your problem.