In this post, I will share a tutorial on getting the top tracks and currently playing on Spotify, using the Next.js API. For example, you can see the misc page.
Creating a Spotify App
We need to do this to get the credentials that will be used to authenticate the API.
- Go to Spotify Developer Dashboard and log in to your account.
- Click "Create an App".
- Fill in the name and description then click "Create".
- Click "Show Client Secret".
- Save Client ID and Secret to
.env
file. - Click "Edit Settings".
- Add
http://localhost:3000
to redirect URIs.
Authentication
We need to get the authorization code
by doing a request via a URL filled with the required parameters.
Please copy the URL below. Change client_id
and scope
as you like. Since in this tutorial we only want to read the top track and the currently playing, we only need scope user-top-read and user-read-currently-playing, you can read more about scope here.
https://accounts.spotify.com/id/authorize?
client_id=9b11ebc6d65840eebb0db51c15b211eb&response_type=code&
redirect_uri=http://localhost:3000/&scope=user-top-read%20user-read-currently-playing
After authorization, you will be redirected to your redirect_uri
earlier. In the URL, there is a code
query parameter. Save that value.
http://localhost:3000/?code=AQCaXamT6nbRDghdG...dyRPlQ
Next, we need a refresh_token
. You have to generate a Base 64 encoded string containing the client ID and secret from earlier. You can use this tool to encode it. The format should be client_id:client_secret
.
curl -H "Authorization: Basic <base64 encoded client_id:client_secret>" -d grant_type=authorization_code -d code=<code> -d redirect_uri=http://localhost:3000/ https://accounts.spotify.com/api/token
Change the command above according to your data. If so, it should be like this. (some of my data will be disguised)
curl -H "Authorization: Basic OWIxMWViYzZkN...UyZDYwZGI=" -d grant_type=authorization_code -d code=AQCaXamT6nbRDghdG...dyRPlQ -d redirect_uri=http://localhost:3000/ https://accounts.spotify.com/api/token
After doing POST request, you will receive a JSON as below.
{
"access_token": "BQCr_Gc6LyFHnu3R0dC...uOU2xXYLs",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "AQDB5wwm...g9tTcaqKc",
"scope": "user-read-currently-playing user-top-read"
}
Using the Spotify API
We have managed to get all the necessary data. Next, create a .env.local
file and fill it with the values you got earlier.
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
SPOTIFY_REFRESH_TOKEN=
We have to request access_token
using the client ID, client secret, and refresh_token we got earlier.
import qs from "query-string"
const client_id = process.env.SPOTIFY_CLIENT_ID
const client_secret = process.env.SPOTIFY_CLIENT_SECRET
const refresh_token = process.env.SPOTIFY_REFRESH_TOKEN
const basic = Buffer.from(`${client_id}:${client_secret}`).toString("base64")
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`
const getAccessToken = async () => {
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: {
Authorization: `Basic ${basic}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: qs.stringify({
grant_type: "refresh_token",
refresh_token,
}),
})
return response.json()
}
We will use this access_token
to request top tracks. I assume you entered the user-top-read
scope in the scope section earlier.
const TOP_TRACKS_ENDPOINT = `https://api.spotify.com/v1/me/top/tracks`
export const getTopTracks = async () => {
const { access_token } = await getAccessToken()
const url = qs.stringifyUrl({
url: TOP_TRACKS_ENDPOINT,
query: {
time_range: "short_term",
},
})
return await fetch(url, {
headers: {
Authorization: `Bearer ${access_token}`,
},
})
}
In the above code, there is a query time_range
, because I want to get the top track for the past 4 weeks, so I added short_term
, you can read about time_range
here.
Creating API endpoints
First you have to create a new file in pages/api/spotify/top-tracks.js
. Then import the getTopTracks
function that we created earlier.
import { getTopTracks } from "../../lib/spotify"
export default async (_, res) => {
const response = await getTopTracks()
const { items } = await response.json()
const tracks = items.slice(0, 10).map((track) => ({
album: track.album.name,
albumImageUrl: track.album.images[0].url,
artist: track.artists.map((_artist) => _artist.name).join(", "),
title: track.name,
duration: track.duration_ms,
songUrl: track.external_urls.spotify,
}))
return res.status(200).json({ tracks })
}
This will give you the top 10 songs that you play most frequently. You can change the code above as you wish. If you have done all the things above, you will get data like below.
{
"tracks": [
{
"album": "Celebrate",
"albumImageUrl": "https://i.scdn.co/image/ab67616d0000b273c5b34e22c26ee36af18aa30b",
"artist": "TWICE",
"title": "Celebrate",
"duration": 188433,
"songUrl": "https://open.spotify.com/track/5ZwlnR8yGofZ0669mEh8Xm"
},
{
"album": "Dawn FM",
"albumImageUrl": "https://i.scdn.co/image/ab67616d0000b2734ab2520c2c77a1d66b9ee21d",
"artist": "The Weeknd",
"title": "Sacrifice",
"duration": 188918,
"songUrl": "https://open.spotify.com/track/1nH2PkJL1XoUq8oE6tBZoU"
},
{
"album": "井上陽水トリビュート",
"albumImageUrl": "https://i.scdn.co/image/ab67616d0000b2733a7b98fc91b7cf4b31f0852b",
"artist": "ヨルシカ",
"title": "Make-up Shadow",
"duration": 237733,
"songUrl": "https://open.spotify.com/track/0ddW75PWqkWQxDOtKLmoQC"
}
// ...........
]
}