DEV Community

Cover image for Adding Spotify Now Playing to Your React App
Jumbo Daniel
Jumbo Daniel

Posted on

Adding Spotify Now Playing to Your React App

I was trying to build a currently playing Spotify feature recently, but still, I didn't want to do this the "traditional" way of getting my keys, fetching the access token, and then adding the respective APIs...... It is way too tedious, I searched around, and then I found this React Package Now Playing.
Shout out to bolajiolajide and lilpolymath. It is lightweight and easy to understand and reduces a lot of boilerplate code compared to using the APIs ourselves. Let's get started. There are three steps: creating the application on the Spotify developer dashboard and authentication.

⁠Note that in this tutorial I'll assume that you have a React app running already, If not you can run:
npx create-next-app@latest

Creating an Application

  • Visit the Spotify Developer Dashboard (https://developer.spotify.com/dashboard/).
  • Log in with your Spotify account or create one if needed.
  • Click the "Create an App" button.
  • Enter a name and description for your application.
  • Click "Create" to generate your app.
  • On your app's page, find your Client ID and Client Secret(copy them; you'll need them soon).
  • Add http://localhost:3000 as your Redirect URIs in the app settings.

Authenticating the App

We will use Authorization Code Flow since we need to authenticate our users once. There are different ways of authenticating Spotify apps, more on that here.
⁠Firstly we can request authorization for our apps by adding our scopes, client_id, and redirect_uri to this URL.
Tip: The now-playing package requires these two scopes user-read-currently-playing and user-read-recently-played so be sure to add them.

https://accounts.spotify.com/authorize?client_id=e2c197e9......d3f35ee5&response_type=code&redirect_uri=http://localhost:3000&scope=user-read-currently-playing user-read-recently-played
Enter fullscreen mode Exit fullscreen mode

You can also use Postman to generate the URL, here is a blogpost that uses Postman
⁠Note that the redirect_uri here has to be the same as the one you added to your Spotify dashboard.
After adding your client_id and scopes, paste the URL into your browser. You'll need to authorize your app afterwards it will redirect you to your app(the redirect_uri you specified). In the URL there is a code parameter, copy it out.

http://localhost:3000/?code=AQBKvAjSrH............7o7wZ6g6fENyVIxfUqNF
Next up, you will have to generate the refresh_token, we will have to generate the base64 string from the client_id and client_secret. You can use any of these tools ⁠Base 64 Encode, Henry's Codepen. With the format client_id:client_secret.

curl.exe -H 'Authorization: Basic <Base 64 encoded client_id:client_secret>' -X POST https://accounts.spotify.com/api/token -d code=<code> -d redirect_uri=http://localhost:3000 -d grant_type=authorization_code
Enter fullscreen mode Exit fullscreen mode

Tip: remove the .exe if you are using a mac
This should return a JSON with the refresh and access token, copy the refresh token(it is valid until revoked access)

{
  "access_token": "....",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": ".....",
  "scope": "user-read-currently-playing user-read-recently-played"
}

Enter fullscreen mode Exit fullscreen mode

Using the Now Playing Package

Install the package

⁠pnpm i @bolajiolajide/now-playing

Add your refresh_token, client_id, client_secret to your env.local file

NEXT_PUBLIC_SPOTIFY_CLIENT_ID= 
NEXT_PUBLIC_SPOTIFY_CLIENT_SECRET= 
NEXT_PUBLIC_SPOTIFY_REFRESH_TOKEN= 
Enter fullscreen mode Exit fullscreen mode

Note: In this tutorial, I'm using NEXT_PUBLIC prefix for the Spotify credentials. It's worth noting, this is more of an experimental setup for me to test Next Export later on. Here's the deal: using NEXT_PUBLIC on these variables isn't exactly best practice. It's like leaving your house keys under the doormat - not the safest move. You're exposing your Spotify API credentials to the client side, which is risky. If you haven't worked with environment variables in Next before, read this first
Instead, you might want to check out:

  • API routes
  • Server-side props
  • Serverside components(App Router)

Create a Now Playing component, import the now-playing package, and write this code

import { NowPlaying, Providers } from "@bolajiolajide/now-playing";

export async function SpotifyPlaying() {
  const client_id = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_ID;
  const client_secret = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_SECRET;
  const refresh_token = process.env.NEXT_PUBLIC_SPOTIFY_REFRESH_TOKEN;
  const np = new NowPlaying(Providers.SPOTIFY, {
    useCache: true, // (optional) default is true
    cacheDuration: 30000, // (optional) in milliseconds
    streamerArgs: {
      clientId: client_id,
      clientSecret: client_secret,
      refreshToken: refresh_token,
    },

  });
  const Playing = await np.fetchCurrentlyPlayingOrLastPlayed();
  return Playing;
}
Enter fullscreen mode Exit fullscreen mode

Afterward, the function returns the recently played or currently playing song already formatted to return title,artiste, image_url

{
    "is_playing": true,
    "title": "Doomsday",
    "artiste": "MF DOOM, Pebbles The Invisible Girl",
    "image_url": "https://i.scdn.co/image/ab67616d0000b2736ce90ec627a0198a8efd127f",
    "preview_url": "https://p.scdn.co/mp3-preview/245f1806f86179d9707001d803c94f7e33d07e0b?cid=e2c197e9a1904790b76c1d07d3f35ee5",
    "url": "https://open.spotify.com/track/7EQvdUJqZ2i7SWvSB2VqGA"
}  
Enter fullscreen mode Exit fullscreen mode

Feel free to style it however you like

Conclusion

This blog post isn't opinionated or one-size-fits-all of building a Now Playing component. I've shown you one way to do it, but there's a whole lot of possibilities out there. You might want to explore using API routes to keep your Spotify credentials safe on the server side. Or maybe you want to turn it up a notch and try out TanStack Query and handle loading, fetching and caching. These methods could give you better performance and security compared to our direct approach. The key is to find what works best for your project and coding style.

⁠A big shoutout to Lee Rob for his fantastic blogpost, which heavily influenced the setup in this tutorial.

Top comments (0)