Introduction
Spotify provides an API that allows developers to fetch real-time data about a user's currently playing track. In this guide, we'll integrate the Spotify API into a Next.js application to display the currently playing song on a webpage. We'll use Next.js server functions, useSWR
for client-side fetching, and environment variables to keep sensitive credentials secure.
Prerequisites
Before we begin, ensure that you have the following:
- A Next.js project set up
- A Spotify Developer Account (Spotify Developer Dashboard)
- The following Spotify API credentials:
- Client ID
- Client Secret
- Refresh Token
Setting Up Environment Variables
Create a .env.local
file in the root of your project and add the following variables:
1SPOTIFY_CLIENT_ID="your-client-id" 2SPOTIFY_CLIENT_SECRET="your-client-secret" 3SPOTIFY_REFRESH_TOKEN="your-refresh-token"
Make sure not to commit this file by adding .env.local
to your .gitignore
file.
Fetching Spotify Data
Create a new file at lib/spotify.ts
to handle Spotify API interactions:
1import axios from 'axios'; 2import querystring from 'querystring'; 3 4const { 5 SPOTIFY_CLIENT_ID: client_id, 6 SPOTIFY_CLIENT_SECRET: client_secret, 7 SPOTIFY_REFRESH_TOKEN: refresh_token, 8} = process.env; 9 10const token = Buffer.from(`${client_id}:${client_secret}`).toString('base64'); 11const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`; 12const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`; 13 14interface SpotifyData { 15 is_playing: boolean; 16 item: { 17 name: string; 18 external_urls: { 19 spotify: string; 20 }; 21 artists: Array<{ name: string }>; 22 album: { 23 name: string; 24 images: [{ url: string }]; 25 }; 26 }; 27} 28 29const getAccessToken = async () => { 30 const res = await axios.post<{ access_token: string }>( 31 TOKEN_ENDPOINT, 32 querystring.stringify({ 33 grant_type: 'refresh_token', 34 refresh_token, 35 }), 36 { 37 headers: { 38 Authorization: `Basic ${token}`, 39 'Content-Type': 'application/x-www-form-urlencoded', 40 }, 41 } 42 ); 43 44 return res.data.access_token; 45}; 46 47export const getNowPlaying = async () => { 48 const access_token = await getAccessToken(); 49 50 return axios.get<SpotifyData>(NOW_PLAYING_ENDPOINT, { 51 headers: { 52 Authorization: `Bearer ${access_token}`, 53 }, 54 }); 55};
This module fetches an access token using the refresh token and then requests the currently playing track from Spotify.
Creating an API Route in Next.js
Next, we'll create a Next.js API route to fetch the currently playing track.
Create a file at /api/spotify/route.ts
:
1import { getNowPlaying } from "@/lib/spotify"; 2 3export const dynamic = 'force-dynamic'; 4 5export async function GET() { 6 try { 7 const response = await getNowPlaying(); 8 9 const data = { 10 title: response.data.item.name, 11 image: response.data.item.album.images[0].url, 12 artists: response.data.item.artists.map(artist => artist.name).join(", "), 13 songUrl: response.data.item.external_urls.spotify, 14 isPlaying: response.data.is_playing, 15 }; 16 17 return Response.json(data); 18 } catch (error) { 19 return new Response('offline'); 20 } 21}
This API route fetches the currently playing song and returns relevant details such as the track name, album image, and artist name.
Displaying the Track on the Frontend
We'll use useSWR
for fetching data on the client side and dynamically update the UI when the song changes.
Create a new component at components/NowPlayingSpotify.tsx
:
1'use client'; 2 3import useSWR from 'swr'; 4import Image from 'next/image'; 5 6type Props = { 7 title: string; 8 image: string; 9 artists: string; 10 songUrl: string; 11 isPlaying: boolean; 12}; 13 14async function fetcher(key: string) { 15 return fetch(key).then((res) => res.json() as Promise<Props | null>); 16} 17 18export const NowPlayingSpotify = () => { 19 const { data, isLoading } = useSWR('/api/spotify', fetcher); 20 21 if (isLoading) return "Loading..."; 22 23 return ( 24 <div className="flex items-center space-x-4"> 25 {data?.image && ( 26 <Image 27 src={data.image} 28 alt={data.title || "Album Cover"} 29 height={64} 30 width={64} 31 className="rounded-lg" 32 /> 33 )} 34 <div> 35 <p className="font-semibold">{data?.title}</p> 36 <p className="text-gray-500 text-sm">{data?.artists}</p> 37 </div> 38 </div> 39 ); 40};
This component fetches data from our API and updates the UI to display the currently playing song.
Using the Component in a Page
Finally, import and use the NowPlayingSpotify
component in your layout or any page:
1import { NowPlayingSpotify } from "@/components/NowPlayingSpotify"; 2 3export default function HomePage() { 4 return ( 5 <div> 6 <h1>Now Playing on Spotify</h1> 7 <NowPlayingSpotify /> 8 </div> 9 ); 10}
explore more