3

How to show Now Playing in Spotify with Next.js

 2 years ago
source link: https://dev.to/theodorusclarence/how-to-show-now-playing-in-spotify-with-next-js-15h5
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Introduction

On my personal website, I use Spotify API to show what song is currently playing. Now, I will try to explain on how do I do that.

Next.js has a built-in API in a single application, so choosing Next.js is a perfect choice so we don't expose our API keys.

Website Demo


1. Create an Application on Spotify Developer

  • Go to Spotify Developer Website.
  • Click Create An App
  • Fill in App Name, App description, then Create
  • Next, you will be provided with Client ID and Client Secret (Don't give this secret to anyone)
  • Open edit settings, then fill out http://localhost:3000 on RedirectURIs

The first step is done! Now, you need to do authentication to get access & refresh token


2. Authenticate Your Account

To do authentication, we need to prepare CLIENT_ID and put it into this link below:

https://accounts.spotify.com/authorize?client_id=CLIENT_ID_HERE&response_type=code&redirect_uri=http
%3A%2F%2Flocalhost:3000&scope=user-read-currently-playing
Enter fullscreen modeExit fullscreen mode

example:

https://accounts.spotify.com/authorize?client_id=eaccb97f6d0e405897adf1dd80b95c01&response_type=code&redirect_uri=http
%3A%2F%2Flocalhost:3000&scope=user-read-currently-playing
Enter fullscreen modeExit fullscreen mode

Open that link in a browser, then you will get redirected into a uri, copy the website link

Example of the redirect link:

http://localhost:3000/?code=AQBeA9SD7QbA9hUfv_TfmatYxT51CY87msMnOZmMbhf7ZaxfbvG7oKEsATOJBxDyFap0Aq6uftY0v4Hq1QSy3MgQBfAHhmrifty-62rfDRlFnd0AzXRBOMpoOSA6SNw_uTPp7AixAE5zosgiIIf7efhzf1QOJfLh1HUYi248z8jk1x2jjKG2YLvMyJuP0rjB5tP5UHjoFGBvKbULpchkF6yiJHnS
Enter fullscreen modeExit fullscreen mode

code that you have is the one after (=). Don't forget to write it down.

Next we need to get authorization client that is already encrypted with base64, use this website to encrypt with the format of client_id:client_secret

For example:

Next, write down the encrypted base64

After that, open up terminal/cmd, and run this command, don't forget to change the base64 and the code to yours.

curl -H "Authorization: Basic CHANGE_BASE64_HERE"
-d grant_type=authorization_code -d code=CHANGE_CODE_HERE -d redirect_uri=http%3A
%2F%2Flocalhost:3000 https://accounts.spotify.com/api/token
Enter fullscreen modeExit fullscreen mode

*make sure the command is in one line

Example:

curl -H "Authorization: Basic ZWFjY2I5N2Y2ZDBlNDA1ODk3YWRmMWRkODBiOTVjMDE6YTQxOTVjMmQwYTQyNDM2MDllNjk3ZTYwMmU3MGI3NjI=" -d grant_type=authorization_code -d code=AQBeA9SD7QbA9hUfv_TfmatYxT51CY87msMnOZmMbhf7ZaxfbvG7oKEsATOJBxDyFap0Aq6uftY0v4Hq1QSy3MgQBfAHhmrifty-62rfDRlFnd0AzXRBOMpoOSA6SNw_uTPp7AixAE5zosgiIIf7efhzf1QOJfLh1HUYi248z8jk1x2jjKG2YLvMyJuP0rjB5tP5UHjoFGBvKbULpchkF6yiJHnS -d redirect_uri=http%3A%2F%2Flocalhost:3000 https://accounts.spotify.com/api/token
Enter fullscreen modeExit fullscreen mode

You will get a JSON like this:

{
  "access_token": "BQDKxO7h1I1wA3esGK9zCFWn97XORJEPjwAHAEIxCnDXcmy9GbEuPacquwWvpiM4d33gJVHVOP9KUxY8AXkpXc-_zRFZBfneHM2vEeV1Fbfr-0Mw94oimlNf77dRiyxPpm4IUVNLloUWgYcfkAO0",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "AQAtxXvnzRTt4c2-2_Av2WyJQKWxUW_hMVN6QNiqv2i8A2ZElVarmvdhqyc8Pf-Z5n827FTFxTpHq5E3kOsrlRWM3TuJWxjVQsW0icR0zo3BXRFLt2FB2Qfj-pFaZwY-qc8",
  "scope": "user-read-currently-playing"
}
Enter fullscreen modeExit fullscreen mode

Example on the terminal:

what we need to write down is the refresh_token. That token will last infinitely

Now you can do the request with Next.js or another backend application


3. Creating API routes in Next.js

If you need a reference to create the app, you can check my repository. Don't forget to star it!

You can also use my nextjs-tailwind-starter by using:

npx create-next-app -e https://github.com/theodorusclarence/nextjs-tailwind-starter project-name
Enter fullscreen modeExit fullscreen mode

or, if you prefer typescript, there is also a starter template

After all app is installed, add querystring dependency

yarn add querystring

or

npm i querystring
Enter fullscreen modeExit fullscreen mode

Next, make an api route in /pages/api/spotify.js

// /pages/api/spotify.js
import querystring from 'querystring';

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

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 getAccessToken = async () => {
  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,
    }),
  });

  return response.json();
};

export const getNowPlaying = async () => {
  const { access_token } = await getAccessToken();

  return fetch(NOW_PLAYING_ENDPOINT, {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
};

export default async (_, res) => {
  const response = await getNowPlaying();

  if (response.status === 204 || response.status > 400) {
    return res.status(200).json({ isPlaying: false });
  }

  const song = await response.json();
  const isPlaying = song.is_playing;
  const title = 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.external_urls.spotify;

  return res.status(200).json({
    album,
    albumImageUrl,
    artist,
    isPlaying,
    songUrl,
    title,
  });
};
Enter fullscreen modeExit fullscreen mode

Add .env.local with authorization data that we have written (change the data below with yours)

SPOTIFY_CLIENT_ID=eaccb97f6d0e405897adf1dd80b95c01
SPOTIFY_CLIENT_SECRET=a4195c2d0a4243609e697e602e70b7
SPOTIFY_REFRESH_TOKEN=AQAtxXvnzRTt4c2-2_Av2WyJQKWxUW_hMVN6QNiqv2i8A2ZElVarmvdhqyc8Pf-Z5n827FTFxTpHq5E3kOsrlRWM3TuJWxjVQsW0icR0zo3BXRFLt2FB2Qfj-pFaZwY-qc8
Enter fullscreen modeExit fullscreen mode

Your API is ready with route: GET https://localhost:3000/api/spotify


4. Use API with Next.js

For data fetching, we can use SWR. SWR is a great library that can fetch the API periodically. SWR will do refetching each time we refocus a the window. Also, install react-icons to get the spotify logo.

yarn add swr react-icons

or

npm i swr react-icons
Enter fullscreen modeExit fullscreen mode

Add SWR in pages/index.jsx like this:

import useSWR from 'swr';

export default function Home() {
  const fetcher = (url) => fetch(url).then((r) => r.json());
  const { data } = useSWR('/api/spotify', fetcher);
  return (
    <>
      <section className='bg-gray-600'>
        <main className='flex items-center justify-center'>
          {console.log(data)}
        </main>
      </section>
    </>
  );
}
Enter fullscreen modeExit fullscreen mode

There will be 2 types of JSON data that will be sent by the Spotify API:

  1. When there is no song playing
   {
     "isPlaying": false
   }
Enter fullscreen modeExit fullscreen mode
  1. When there is a song playing
   {
     "album": "Menari Dengan Bayangan",
     "albumImageUrl": "https://i.scdn.co/image/ab67616d0000b273d623688488865906052ef96b",
     "artist": "Hindia",
     "isPlaying": true,
     "songUrl": "https://open.spotify.com/track/08OPqLv99g8avzmxQepmiw",
     "title": "Besok Mungkin Kita Sampai"
   }
Enter fullscreen modeExit fullscreen mode

So, we can conditionally render the data like this:

<a
  target='_blank'
  rel='noopener noreferer'
  href={
    data?.isPlaying
      ? data.songUrl
      : 'https://open.spotify.com/user/erence21?si=yTsrZT5JSHOp7tn3ist7Ig'
  }
  className='relative flex items-center p-5 space-x-4 transition-shadow border rounded-md hover:shadow-md w-72'
>
  <div className='w-16'>
    {data?.isPlaying ? (
      <img
        className='w-16 shadow-sm'
        src={data?.albumImageUrl}
        alt={data?.album}
      />
    ) : (
      <SiSpotify size={64} color={'#1ED760'} />
    )}
  </div>

  <div className='flex-1'>
    <p className='font-bold component'>
      {data?.isPlaying ? data.title : 'Not Listening'}
    </p>
    <p className='text-xs font-dark'>
      {data?.isPlaying ? data.artist : 'Spotify'}
    </p>
  </div>
  <div className='absolute bottom-1.5 right-1.5'>
    <SiSpotify size={20} color={'#1ED760'} />
  </div>
</a>
Enter fullscreen modeExit fullscreen mode

You can check out the live deployment on spotify-playing.theodorusclarence.com


Originally posted on my personal site, find more blog posts and code snippets library I put up for easy access on my site 🚀


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK