How to make a Spotify currently playing widget in React

December 10th, 20235 min read1,400 views

Imagine having your current Spotify track displayed directly in React — pretty cool, right? I've included a detailed step-by-step guide below, allowing you to integrate a React component that showcases the currently playing track on your own site. Just scroll down to get started!

Table of contents#

  1. Step 1: Spotify developer application
  2. Step 2: Refresh Token
  3. Step 3: React Component
  4. That's it!

Step 1: Spotify developer application#

  1. Head over to Spotify Developers — developer.spotify.com
  2. Log in, and navigate to the dashboard and click on the blue Create new button.
  3. Enter in the details of the application, you can also use the details that I've written in the image below.

Spotify Dashboard

  1. Once you've created the app, write down the Client ID and the Client Secret.

Step 2: Refresh Token#

A refresh token is used for generating a new access token.

  1. Replace CLIENT_ID, then copy and navigate to the URL below. The user-read-currently-playing part of the URL is a scope that is used for accessing the track that you are currently listening to.
sh
https://accounts.spotify.com/en/authorize?client_id=CLIENT_ID&response_type=code&redirect_uri=http://localhost:3000&scope=user-read-currently-playing
  1. After authorizing, you'll be redirected to the redirect URI. In the search bar, you'll see a looong code in the code search parameter. Make note of the value.
sh
http://localhost:3000/?code=YOUR_CODE
  1. We require a base64 encoded string including the Client ID and Secret from before in the format clientid:clientsecret to generate a refresh token. You can generate the string at base64encode.org.

  2. After encoding the string, replace YOUR_ENCODED_STRING and YOUR_CODE, then run the cURL command below at reqbin.com/curl.

sh
curl -H "Authorization: Basic YOUR_ENCODED_STRING" -d grant_type=authorization_code -d code=YOUR_CODE -d redirect_uri=http://localhost:3000 https://accounts.spotify.com/api/token

After running the command, you'll receive a JSON response with the refresh token. Make note of the refresh_token.

json
{
  "access_token": "super-secret-access-token",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "super-secret-refresh-token",
  "scope": "user-read-currently-playing"
}

Step 3: React Component#

  1. Store the CLIENT_ID, CLIENT_SECRET and REFRESH_TOKEN in a .env file.
  2. These 2 variables below are the endpoints that we'll be using.
ts
const CURRENTLY_PLAYING_ENDPOINT =
  "https://api.spotify.com/v1/me/player/currently-playing";
const TOKEN_ENDPOINT = "https://accounts.spotify.com/api/token";
  1. Create a function that we'll use later on to generate an access token.
ts
import { TOKEN_ENDPOINT } from "path/to/file";
 
const { CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN } = process.env;
 
async function getAccessToken(): Promise<string> {
  // encode the Client ID and Client Secret in base64
  const basic = Buffer.from(`${CLIENT_ID!}:${CLIENT_SECRET!}`).toString(
    "base64"
  );
 
  // create url search parameters /?grant_type=refresh_token&refresh_token=REFRESH_TOKEN
  const body = new URLSearchParams({
    grant_type: "refresh_token",
    refresh_token: REFRESH_TOKEN!,
  });
 
  // make a POST request to the Spotify token endpoint requesting an access token
  const response = await fetch(TOKEN_ENDPOINT, {
    method: "POST",
    headers: {
      Authorization: `Basic ${basic}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: body.toString(),
  });
 
  return response.json().then((x) => x?.access_token);
}
  1. If using TypeScript, you can use this type below as for the Spotify currently playing response. If you want to extend this type because you think you need more types, you can go to the Spotify Developer Documentation.
ts
export interface ISpotifyResponse {
  repeat_state: "off" | "track" | "context";
  shuffle_state: boolean;
  progress_ms: number | null;
  item: {
    name: string;
    album: {
      name: string;
      images: { url: string }[];
      artists: { name: string }[];
    };
    preview_url: string | null;
    external_urls: { spotify: string };
    uri: string;
    duration_ms: number;
    type: "track";
  } | null;
  currently_playing_type: "track" | "episode" | "unknown";
  is_playing: boolean;
}
  1. Now create a function that fetches the song details from the currently playing endpoint. Please note that this function will return null if the request fails, so make sure that you implement proper error handling if you wish.
ts
async function getCurrentlyPlaying(): Promise<ISpotifyResponse | null> {
  try {
    // get the access token using the refresh token
    const accessToken = await getAccessToken();
 
    // fetch the data from the currently playing endpoint using the access token
    const response = await fetch(CURRENTLY_PLAYING_ENDPOINT, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
 
    // if the request hasn't succeeded
    if (!response.ok) {
      // implement error handling
      return null;
    }
 
    const data = await response.json();
 
    // if the currently playing type is not "track"
    if (data.currently_playing_type !== "track") {
      // implement error handling
      return null;
    }
 
    return data;
  } catch (error) {
    // implement error handling
    return null;
  }
}
  1. Create a React component which will display the data from Spotify. This is a very basic example of periodically fetching the data.
tsx
import { getCurrentlyPlaying } from "path/to/file";
import { useEffect, useState } from "react";
 
export default function CurrentlyPlayingComponent() {
  const [currentlyPlaying, setCurrentlyPlaying] =
    useState<ISpotifyResponse | null>(null);
 
  const [isLoading, setIsLoading] = useState(true);
 
  useEffect(() => {
    // fetch the data and store it in a state
    const fetchCurrentlyPlaying = async () => {
      const data = await getCurrentlyPlaying();
      setCurrentlyPlaying(data);
      setIsLoading(false);
    };
 
    // fetch when the page gets loaded
    fetchCurrentlyPlaying();
 
    // refetch every 5 seconds (you may change this to your liking, keep in mind that Spotify has rate limits)
    setInterval(() => {
      fetchCurrentlyPlaying();
    }, 5 * 1000);
  }, []);
 
  // if there is no response yet from the fetch request
  if (isLoading) {
    return <p>Loading...</p>;
  }
  // if not listening to anything
  else if (!currentlyPlaying || !currentlyPlaying.item) {
    return <p>Not listening to anything.</p>;
  }
  // display the song artist(s) and song name e.g. Artist1, Artist2 - Name
  else {
    return (
      <p>{`${currentlyPlaying.item.album.artists
        .map((artist) => artist.name)
        .join(", ")} - ${currentlyPlaying.item.name}`}</p>
    );
  }
}

That's it!#

You're all set now! Congratulations on implementing the Spotify currently playing track display in your React application. Enjoy showcasing your favorite tunes on your own site. If you have any questions or feedback, feel free to reach out. Happy coding!

Enjoyed the article?