DEV Community

Bojan Jagetic
Bojan Jagetic

Posted on • Updated on • Originally published at bojanjagetic.com

Spotify API for creating 'Listening now' card with Nextjs

Introduction

In this blog post, we'll explore a code snippet that demonstrates how to create a Spotify API wrapper using Next.js and the popular HTTP client library, Axios. This code we will write, will allows you to fetch information about the currently playing track on your Spotify account and retrieve details such as the song title, artist, album, album cover image URL, and the Spotify song URL. Its up to you to show whatever you like, this is my example which I am currently using on my personal webiste so feel free to be creative as much as you like. So I will not bother anymore, let's dive into the code and understand how it works.

Idea behind project

Nothing special to be honest, as I mentioned already above I wanted to show which music I am currently listening on Spotify and who knows, maybe some uknown visitor likes the song so at least I can do in this case is recommend some good music :)

Code Explanation

The code begins with the requiring neccessarry modules for this project, querystring and axios, are imported. querystring is used to stringify the request parameters (you dont have to use it, I already had it in project so find a good use of it but its not necessarry), while axios is used to make HTTP requests to the Spotify API.

The following code retrieves the required environment variables, which are named SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, and SPOTIFY_REFRESH_TOKEN, using destructuring assignment from the process.env object. These variables store sensitive information and should be kept secure so thats why it is strongly recommended to use environment variable. Be aware that you have to get your tokens from spotify developer portal.

The token variable is then created by encoding the client_id and client_secret using Base64 encoding. It will be used for authentication as a bearer token when we want to request an access token from Spotify.

Two constants, NOW_PLAYING_ENDPOINT and TOKEN_ENDPOINT, store the Spotify API endpoints for retrieving currently playing track information and obtaining access tokens, respectively.

import querystring from 'querystring'
import axios from 'axios'

const {
  SPOTIFY_CLIENT_ID: client_id,
  SPOTIFY_CLIENT_SECRET: client_secret,
  SPOTIFY_REFRESH_TOKEN: refresh_token
} = process.env

const token = Buffer.from(`${client_id}:${client_secret}`).toString('base64')
const NOW_PLAYING_ENDPOINT = 'https://api.spotify.com/v1/me/player/currently-playing'
const TOKEN_ENDPOINT = 'https://accounts.spotify.com/api/token'

Enter fullscreen mode Exit fullscreen mode

The getAccessToken function, as already said, will be used for fetching access token from Spotify, it sends a POST request to the TOKEN_ENDPOINT https://accounts.spotify.com/api/token with the necessary parameters, including the grant_type set to refresh_token and the refresh_token obtained from the environment variables. The request includes the Authorization header with the encoded client_id and client_secret. The response data, which contains the access token, is returned.

const getAccessToken = async () => {
  const response = await axios.post(
    TOKEN_ENDPOINT,
    querystring.stringify({
      grant_type: 'refresh_token',
      refresh_token
    }),
    {
      headers: {
        Authorization: `Basic ${token}`,
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }
  )

  return response.data
}
Enter fullscreen mode Exit fullscreen mode

Lets move on to the getNowPlaying function is another asynchronous function that retrieves the currently playing track information from the NOW_PLAYING_ENDPOINT API https://api.spotify.com/v1/me/player/currently-playing. It first calls getAccessToken to obtain the access token, then sends a GET request to the NOW_PLAYING_ENDPOINT with the access token included in the Authorization header.

export const getNowPlaying = async () => {
  const { access_token } = await getAccessToken()
  return axios.get(NOW_PLAYING_ENDPOINT, {
    headers: {
      Authorization: `Bearer ${access_token}`
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

Finally, we are coming to the callSpotifyApi function which will be exported as a default and will be called. It calls getNowPlaying to get the currently playing track information. If the response status is 204 (no content) or an error occurs, it will send a JSON response indicating that nothing is currently playing so you should show something else. Otherwise, if there is some song playing, it extracts relevant data from the response and constructs a JSON object containing details about the currently playing track.


const spotifyApi = async (_, res) => {
  const response = await getNowPlaying()
  if (
    response.status === 204 || response.status > 400 || (response.data && response.data.currently_playing_type !== 'track')
  ) {
    return res.status(200).json({ isPlaying: false })
  }

  const data = {
    isPlaying: response.data.is_playing,
    title: response.data.item.name,
    album: response.data.item.album.name,
    artist: response.data.item.album.artists.map((artist) => artist.name).join(', '),
    albumImageUrl: response.data.item.album.images[0].url,
    songUrl: response.data.item.external_urls.spotify
  }

  res.status(200).json(data)
}

export default spotifyApi

Enter fullscreen mode Exit fullscreen mode

So finally, here is spotify.js file, completed.

/* eslint-disable camelcase */
// /pages/api/spotify.js
import querystring from 'querystring'
import axios from 'axios'

const {
  SPOTIFY_CLIENT_ID: client_id,
  SPOTIFY_CLIENT_SECRET: client_secret,
  SPOTIFY_REFRESH_TOKEN: refresh_token
} = process.env

const token = Buffer.from(`${client_id}:${client_secret}`).toString('base64')
const NOW_PLAYING_ENDPOINT = 'https://api.spotify.com/v1/me/player/currently-playing'
const TOKEN_ENDPOINT = 'https://accounts.spotify.com/api/token'

const getAccessToken = async () => {
  const response = await axios.post(
    TOKEN_ENDPOINT,
    querystring.stringify({
      grant_type: 'refresh_token',
      refresh_token
    }),
    {
      headers: {
        Authorization: `Basic ${token}`,
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }
  )

  return response.data
}

export const getNowPlaying = async () => {
  const { access_token } = await getAccessToken()
  return axios.get(NOW_PLAYING_ENDPOINT, {
    headers: {
      Authorization: `Bearer ${access_token}`
    }
  })
}

const spotifyApi = async (_, res) => {
  const response = await getNowPlaying()
  if (
    response.status === 204 || response.status > 400 || (response.data && response.data.currently_playing_type !== 'track')
  ) {
    return res.status(200).json({ isPlaying: false })
  }

  const data = {
    isPlaying: response.data.is_playing,
    title: response.data.item.name,
    album: response.data.item.album.name,
    artist: response.data.item.album.artists.map((artist) => artist.name).join(', '),
    albumImageUrl: response.data.item.album.images[0].url,
    songUrl: response.data.item.external_urls.spotify
  }

  res.status(200).json(data)
}

export default spotifyApi
Enter fullscreen mode Exit fullscreen mode

Spotify card

So basically for Spotify card you can make whatever you like, so feel free to make it by your preferences. I have been using in this project Next.js with Tailwind and for calling Spotify API I used SWR which is basically 'React Hook for Data Fetching', but if you want to find more about that topic you can check my other post What is SWR and How Can It Improve Your React Apps.
So here is how it is looking inside of my app when I am not listening anything:

Spotify card not playing

So here is how it is looking inside of my app when I am listening :

Spotify card playing

Spotify card playing zoomed

Conclusion

In this blog post, we explored a code snippet that demonstrates how to create a Spotify API wrapper using Next.js and Axios, simple as that. The code allows you to fetch information about the currently playing track on Spotify and retrieve details such as the song title, artist, album, album cover image URL, and the Spotify song URL. You can use this code as a starting point to build more advanced Spotify-related functionality in your applications or you can get some more better idea. Feel free to modify and extend the code to suit your specific requirements this is just my type but you can make it however you wish. I hope I helped, if you have any question please let me know and Happy coding!

Top comments (2)

Collapse
 
ferpmdev profile image
Fernando Pioli Martínez

excellent!!!
Question: I suppose that for this I'll need to install cypress, because it will allow me use Buffer in pages/api/spotify.js.
Do you remember if it require some additional configuration?
Thanks a lot for share your knowledge & code!!!

Collapse
 
basskibo profile image
Bojan Jagetic

Sorry for late response, comment got under my radar :(
For starter thank you very much for kind words, really appreciate this.
It depends on your use case, as for pages/api/spotify.js you can use other testing libaries like jest, chai, mocha ,etc. as it is on server side so not sure if cypress will do the work.
For more feel informations and questions feel free to ping me :)