You need to follow these step by step guide in order to integrate Spotify's API.
1. CREATE AN APPLICATION
Firstly, you need to authenticate yourself in order to get access for fetching the Spotify's API.And, for that you need to create an spotify application. Here are the steps:
- Go to your Spotify developer dashboard and log in to your account.
- Then, click on Create app button just below the navbar on top right corner of your dashboard.
- Next, fill all the fields, App name, App description,Website and on Redirect URIs field, type
http://localhost:3000
as your redirect URI. - Then click on Save.You will be redirected to your newly created app now.
- Next, click on Settings on top right corner, just below the navbar.There you will get your
client_id
and just below that you will see View client secret button. - Now, click on that button and save both
client_id
andclient_secret
.Both will be needed later.
Congratulations!, now you have all credentials in order to authenticate the Spotify's APIs.
2. AUTHORIZATION
Now, it's time to authenticate the Spotify API using the previously saved credentials. Spotify offers various Authorization methods, and for now, we'll be utilizing the Authorization Code Flow.
Initially, our application needs to be authorized with specific
scopes. Scopes
serve the purpose of granting confidence to share only the selected information and nothing beyond that.
For instance, in my application, I only intend to retrieve the top ten tracks and the currently playing song
from Spotify's Developer API. To achieve this, I must select the scopes user-top-read
and user-read-currently-playing
from the scopes list respectively.
Here's an example of the URL for authorization with these scopes.
https://accounts.spotify.com/authorize?client_id=<client_id_you_saved_before>&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000&scope=user-read-currently-playing%20user-top-read
Now, copy the provided URL and paste it into your browser's address bar. Ensure that your localhost:3000
is running.
is actively running. After pressing enter, you'll be redirected to http://localhost:3000?code=
, where you will receive
a code as a query parameter. Here's an example of the URL you can expect at this stage.
http://localhost:3000/?code=AQB3x..............................
Now, save this code.You will need it later for retrieving your refresh_token
.
Next, you will need to generate the refresh_token
in order to revoke the access_token
--which expires frequently.For that
open up your terminal and then type the following code.
curl -d client_id=<your_client_id> -d client_secret=<your_client_secret> -d grant_type=authorization_code -d code=<code_that_you_saved_from_redirected_uri> -d redirect_uri=http://localhost:3000 https://accounts.spotify.com/api/token
You now will get the JSON response in the following format.
{
"access_token":"your_access_token_here",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"your_refresh_token_here",
"scope":"user-read-currently-playing"
}
After that save the refresh_token
from the response and save it for later.You will need to use this in Next.js application. This refresh_token
is valid indefinitely until
and unless the user it represents revokes access.
3.Using Spotify's API in Next.js(14.0.1) App router
Firstly, you have to set up the environment variables
in .env
file outside the app
directory in your next js application.Add the environment variables as below.Replace these values
with your own values you saved before like before.
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
SPOTIFY_REFRESH_TOKEN=
Secondly, let's create a lib/spotify.js
, to look more organized folder structure, where we will be writing the API fetching
logic. Your code should look like this.
import queryString 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 NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`;
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`;
const TOP_TRACKS_ENDPOINT = `https://api.spotify.com/v1/me/top/tracks`;
//After the access_token expires, getting new access_token with refresh_token we obtained before
const getAccessToken = async () => {
try {
const response = await fetch(TOKEN_ENDPOINT,{
method:'POST',
headers:{
Authorization:`Basic ${basic}`,
'Content-Type':'application/x-www-form-urlencoded'
},
body:queryString.stringify({
grant_type:'refresh_token',
refresh_token
})
});;
const responseData = await response.json();
return responseData;
} catch(err){
throw new Error(JSON.stringify(err))
}
};
//Get currently playing song
export const getNowPlaying = async () => {
try {
const {access_token} = await getAccessToken();
return fetch(NOW_PLAYING_ENDPOINT,{
headers:{
Authorization:`Bearer ${access_token}`
}
});
} catch(err){
throw new Error(JSON.stringify(err))
}
};
//Get top tracks played on your Spotify account
export const getTopTracks = async () => {
try {
const {access_token} = await getAccessToken();
return fetch(TOP_TRACKS_ENDPOINT,{
headers:{
Authorization:`Bearer ${access_token}`
}
});
} catch(err){
throw new Error(JSON.stringify(err))
}
};
4.Creating an API route
Cheers 🥂!, Everything is setup. Now at last we need to setup two api routes in order to send the requests
and get response from the spotify's API. For that you have to create two files app/api/now-playing/route.js
and app/api/top-tracks/route.js
in your application.The equivalent code for those two endpoints looks like this.
import { NextResponse } from 'next/server'
import {getNowPlaying} from "../../../lib/spotify";
export const dynamic = 'force-dynamic';
//--------------OR---------------------//
export const revalidate = 0;
export async function GET(request) {
const response = await getNowPlaying();
if(response?.status === 204 || response?.status > 400) {
return NextResponse.json({isPlaying:false},{status:200});
}
try {
const song = await response.json();
console.log('song',song?.item?.name);
const isPlaying = song?.is_playing;
const name = song?.item?.name;
const artist = song?.item?.artists.map((_artist) => _artist.name).join(", ");
const album = song?.item?.album.name;
const albumImageUrl = song?.item?.album.images[0].url;
const songUrl = song?.item?.album.external_urls.spotify;
return NextResponse.json({
isPlaying,
album,
albumImageUrl,
name,
songUrl,
artist
},{
status:200
});
} catch(err) {
return NextResponse.json({
isPlaying:false
},{
status:200
});
}
}
import { NextResponse } from 'next/server'
import {getTopTracks} from "../../../lib/spotify";
export const dynamic = 'force-dynamic';
//--------------OR----------------------//
export const revalidate = 0;
export async function GET(request) {
const response = await getTopTracks();
if(response.status === 204 || response.status > 400) {
return NextResponse.json({tracks:[]},{status:200});
}
try {
const {items} = await response.json();
const tracks = items.slice(0,10).map(track => {
return {
artist:track.artists.map(artist => artist.name).join(", "),
songUrl:track.external_urls.spotify,
title:track.name,
imageUrl:track.album.images.map(image => image.url)[1]
};
});
return NextResponse.json({tracks},{
status:200
});
} catch(err){
return NextResponse.json({tracks},{status:200});
}
}
Note: In the provided code, you'll notice two lines as shown below 👇. You can choose either of them; both are optional, and you can select the one you prefer. This flexibility exists because, by default, the Next.js App router caches routes. This means that if the same endpoint is accessed from the client side, the router utilizes the cached response. If you don't use these options, your "now-playing" endpoint may not update, resulting in the same cached response being displayed and causing a failure to show the currently playing music in the UI.Additinally, feel free to modify the JSON response from those endpoints as per your need or demand.
export const dynamic = 'force-dynamic';
//-----------OR----------------------//
export const revalidate = 0;
5.Conclusion
Everything is complete! Now it's time to retrieve data from the two endpoints you've established. This is the way to showcase your top ten tracks and currently playing songs on your Next.js website, allowing users to see what you're listening to.
POV: You have the option to utilize swr, react query or official fetch api or client-side data fetching in React.js. For simplicity, I'll be using swr. Here's a code snippet demonstrating how to implement SWR for this particular use case.
import useSWR from 'swr';
const YourClientComponent = () => {
//Fetch data in a periodical interval of 1 seconds
const {data,error} = useSWR('/api/now-playing',fetcher,{refreshInterval:1000});
return (
<div>
{
error && <p> Oops! Error dude 👀 </p>
}
{
data?.isPlaying ? (<h1>{data?.name}</h1>):<p>Not Playing</p>
}
</div>
)
};
export default YourClientComponent;
Consequently, you can integrate Spotify's API like as such in Next.js APP Router.Follow me on 👉 GitHub.
Keep coding, Keep learning and Keep listening music 🎸.😜😜