How to Authenticate Spotify Web API Requests in Next.js with Netlify API Auth

The web is full of awesome APIs that we can use to add feature sto our apps, but often using those APIs includes a long process of registering an app and figuring out authentication so you can simply make a request. With Netlify’s new API Authentication, we can easily enable third party services and instantly gain access to our favorite tools.

Table of Contents

YouTube Preview
View on YouTube

The end of the year means it’s time to check out the “year in review” for all of the services you use. While those are all fun, we can take that to another level and build our own, like our own version of Spotify’s Wrapped which pulls in all of the music you’ve listened to in the past year.

Spotify has an API?

Yes! A pretty cool one at that.

If you’re a Spotify user, there are a lot of cool projects that you can put together by being able to programmatically access your Spotify account, such as a “Currently Playing” widget or managing your account.

On top of that, Spotify has broader features like search that give you the ability to look up media information like if you wanted to build a search tool to look up information or music availability for your favorite artist

But like I mentioned earlier, it can be a bit of a pain to set up authentication, between registering an application and creating a mechanism to retrieve an oAuth token to make requests with, even if you’re not planning on providing login access for anyone but yourself, which is where Netlify API Auth comes in.

What is Netlify API Authentication?

Netlify announced an acquisition of OneGraph which led to the release of a feature they’re calling API Authentication.

OneGraph was (or still is) a service that allows you to bring together other APIs and services into a single GraphQL endpoint. This includes Authentication for those services.

This opened the door to Netlify being able to integrate OneGraph capabilities into it’s own infrastructure, allowing developers to easily take advantage of authentication with other services like Stripe, Spotify, GitHub, and Salesforce, without having to explicitly create apps or integrations with those services themselves.

Instead, as a Netlify user, you log into the service via oAuth, granting access to your Netlify site, which then allows you to programmatically access authenticated sessions in your Netlify Builds and Functions.

Note: Netlify API Authentication is still in Beta at the time of writing this, so things are subject to change!

What does this have to do with Next.js?

The cool thing about Next.js on Netlify is through the Next.js data fetching functions, we have access to the same Netlify environment where the API Authentication details are made available.

Between building on node and some of the dynamic bits being turned into lambdas on Netlify, we can directly access our authenticated sessions with the services we connect, which allows us to easily tap into those services for building apps with Next.js

What are we going to build?

To check out how this works, we’re going to build an app inspired by Spotify Wrapped that simply lists our top artists and top tracks for the given time.

Website showing top artists from Spotify
my-spotify-rewrapped.netlify.app

Now the only caveat there is via the API, we can only get time ranges of several years, six months, or four weeks, so it won’t really be a standard year, but it’ll be sufficient to see what we’ve been up to on Spotify in the recent past.

To do this, we’re going to enable the API Authentication feature on Netlify via Netlify Labs and connect it to a Netlify Site. Once that’s set up, we’ll then have access to our session, where we can then make whatever requests we want with our given scope to the Spotify API.

In order to develop and see how this works locally, we’ll need to use the Netlify CLI, where Netlify will give us access to our environment just like it would be when deployed. So we’ll additionally install the Netlify CLI and see how we can develop locally with their tool.

Step 0: Creating a new Next.js app from a demo starter

We’re going to start off with a new Next.js app using a starter that will give us a website that has some filler content of a grid of top artists and tracks.

Inside of your terminal, run:

yarn create next-app my-spotify-rewrapped -e https://github.com/colbyfayock/demo-top-music-starter
# or
npx create-next-app my-spotify-rewrapped -e https://github.com/colbyfayock/demo-top-music-starter

Note: feel free to use a different value than my-spotify-rewrapped as your project name!

Once installation has finished, you can navigate to that directory and start up your development server:

cd my-spotify-rewrapped

yarn dev
# or
npm run dev

And once loaded, you should now be able to open up your new app at http://localhost:3000!

App showing Spotify Re-Wrapped title and blink-182 as top 4 artists
Spotify Re-Wrapped

Now of course, your top 4 favorite artists might not all be blink-182, so we’re going to update this in a later step to dynamically pull our top artists from Spotify.

But before we move on, we can check out our code and we’ll see that there’s really nothing special going on at this point, beyond a little bit of layout and styles for a fun starting point.

We’ll be working mostly in src/pages/index.js where we have a list and some list items with images, which we’ll use to dynamically show our top items!

Step 1: Deploying a Next.js app to Netlify

The first step to getting this all working is get our site up to Netlify. This will allow us to enable API Authentication and start to pull all of the pieces together.

The easiest way to do this is to get our app set up on our favorite Git provider supported by Netlify including GitHub, GitLab, or Bitbucket.

I’m going to use GitHub in my walkthrough, but it should really be the same process for any of them.

Once you’re ready, head over to Netlify where we’re going to want to add a new Site, which you can find at the top of the Team overview or Sites page.

Click Add new site and select Import an existing project.

Netlify dashboard showing button to add a new site
Netlify add new site

On the next page, select your Git provider like GitHub, where if this is the first time using Netlify, it will ask you to authenticate.

Once authenticated, you can then search for your repository.

Repository search in Netlify dashboard showing new repo
Selecting GitHub repository

Select your site and on the next page, if you’re following along, we’ll see that Netlify automatically detected that we’re trying to deploy a Next.js project and filled in all of our build settings. It’s even going to install the Essential Next.js Build Plugin so we can deploy Next.js on Netlify!

But that means we can leave all of the settings “as is” and scroll to the bottom where we can then click Deploy site.

At this point, Netlify will start to build and deploy our new project.

Netlify Site Overview showing successful deployment and URL
Deployed Netlify site

Once it’s finished we’ll have it available where we can open it and preview it live on the web!

Tip: you can even change the Netlify subdomain used in Domain settings!

Step 2: Enabling API Authentication and Setting it Up on a Netlify Site

Next, we want to get our Site set up so that we can use Netlify’s new API Authentication feature.

Note: Reminder, API Authentication is still in Beta at the time of writing this, so things might change a bit.

To get started, we first want to enable the feature on our Netlify user account.

To do this, we’ll first head over to the Netlify Labs page at:

https://app.netlify.com/user/labs

Where we’ll see Netlify API Authentication listed under Experimental features.

Click Enable next to that feature.

Netlify Labs page showing enabled Netlify API Authentication
Enabling Netlify API Authentication

Now that we have access on our account, we need to enable the feature on our Site that we just deployed.

Head back over to the Netlify dashboard, find your newly deployed Site, and navigate to the Site settings page.

If you look on the left sidebar all the way at the bottom, you should see a new API Authentication item which you can then click to navigate to.

Similar to Netlify Labs, we now need to enable this feature on our site, so select Enable API Authentication for [your site name], confirm that you want to enable it, where then you’ll see a list of different services we can use.

Netlify API Authentication page showing available services to connect with
API Authentication services

While you can use any of these services, we’re going to use Spotify for our walkthrough, so next to the Spotify option, click Connect where you’ll then be prompted to log in and authenticate with your Spotify account.

Now before we move on, we need to make sure we enable the correct permissions and Scopes so that we can make requests to the API endpoints we want to.

Select the dropdown arrow under the Spotify line where you’ll see a list of options with checkboxes. We want to find the Listening History section and select the checkbox to enable Read your top artists and content.

Netlify API Authentication showing Spotify scopes with "top" option and update button highlighted
Updating Spotify scopes

Then be sure to click Update Spotify scopes before moving on.

But now, our Site is connected to Spotify and we should now be able to start working with their API!

Step 3: Installing the Netlify CLI and connecting a local site

Now this step is technically optional, but I highly recommend it. Without using the Netlify CLI for local development, you might find it more challenging to test that things are working locally before deploying them.

The good news it’s easy to get the CLI installed and configured!

We’re going to install the Netlify CLI via npm globally. That means it’ll be available anywhere on your local environment, even outside of the project.

While we can still use either npm or yarn to run the install command, it’s likely a good idea to make sure you’re always using the same command when installing global packages, as it can get confusing when trying to figure out how you installed when later trying to manage that package.

So that said, I’m going to stick with installing the package globally using standard npm:

npm install netlify-cli -g

Once that finishes installing, you should be able to run:

netlify

Which will show you all of the commands available for the CLI and you’ll know it worked!

Terminal showing netlify command with CLI info
Netlify CLI

Now before we link our project, we also want to log in to our account to make sure we’re authenticated locally in our environment.

Run the command:

netlify login

This will open up a new page in your browser (or give you a URL to open) where you can then click Authorize once logged into your Netlify account.

Terminal showing netlify login command with successful login
Netlify CLI login

Finally, we can link our project!

Inside of your project directory, run:

netlify link

At this point, Netlify will prompt you to connect your Site.

If you’re using Git like discussed earlier and have your local project connected to Git, you can select the first option, which is the easiest, where Netlify will look for the Site that corresponds to the Site we deployed earlier.

Terminal showing netlify link command with link options
Netlify CLI link

Otherwise you’ll need to use the other options to find your Site to connect locally.

But once successfully connected, you’ll see a notification saying your site is ready to go! So now let’s try to spin up our project.

Run:

netlify dev

This will start up a local development server, much like if we started it up without the Netlify CLI, where it should also open the page in a new browser tab.

This should look just like the project from Step 0, but if you notice in the terminal, you should see that Netlify injected build settings into our environment, which is exactly what we need to get started with our Spotify authentication!

Terminal showing the netlify dev command with notification of build settings injected into environment
Netlify dev with injected build settings

Note: you should notice that the Netlify CLI added a new line to your .gitignore which just helps prevent those files from being stored in git

Step 4: Accessing authenticated session information in Next.js with Netlify Function helpers

With our Netlify Site set up and CLI available, we’re ready to get started accessing our authenticated session so that we can make requests to Spotify.

To make this easy, Netlify makes helper methods available for us via the @netlify/functions package.

So first, let’s install that package with:

yarn add @netlify/functions
# or
npm install @netlify/functions

Then we want to import our function to use, so at the top of src/pages/index.js add:

import { getSecrets } from '@netlify/functions';

To access our session and make our request, we’re going to use getStaticProps, which will allow us to make that request securely and pass the data to our app.

At the bottom of src/pages/index.js add:

export async function getStaticProps() {
  return {
    props: {}
  }
}

Tip: you could alternatively use getServerSideProps if you prefer to make the request realtime serverside!

Next, we want to request our secrets.

At the top of getStaticProps add:

const secrets = await getSecrets();

This will allow us to have access to the environment that Netlify is injecting into our project, and particularly, we want to access our secrets and the Spotify session token.

We can see that this is working by using log to see all those details in our terminal. Under the getSecrets request add:

console.log('secrets.spotify', secrets.spotify);

And we can see all of our session information!

Terminal showing logged Spotify session information including highlighted bearerToken value
Spotify token

Particularly, we want the bearerToken. We’ll use this token in our next step to make our request to the Spotify API and load our top artists and songs in the UI.

Follow along with the commit!

Step 5: Using the Spotify Web API to request Top Artists and Top Tracks

Finally, now that we have our Spotify token, we can make an authenticated request to the API.

We’re going to use the Get User’s Top Items endpoint which will allow us to both request our Top Artists and our Top Tracks.

First, let’s make our request to get our Top Artists.

Under our secrets add:

const artistsResponse = await fetch(`https://api.spotify.com/v1/me/top/artists?limit=10`, {
  headers: {
    Authorization: `Bearer ${secrets.spotify.bearerToken}`,
  }
});
const { items: artists } = await artistsResponse.json();

In the above, we’re hitting the Spotify API endpoint to get our artists while passing in an Authorization header along with a our Bearer token designator and our actual token.

Once we have that response, we grab the JSON and destructure (and rename) our artists data.

In our request, we’re limiting to the top 10 artists. Additionally, by default, the endpoint will return the top artists using the medium_term option, which is 6 months.

Tip: Check out the documentation to see how you can configure the API options!

Next, let’s pass it as a prop so that we can access it in our app.

Inside of the return statement add:

return {
  props: {
    artists
  }
}

Then at the top inside of our Home component definition, make our prop available with:

export default function Home({ artists }) {

And now let’s make sure it’s working by adding a log statement right underneath.

Web console showing logged artist data from Spotify
Artist data

Your data will likely look different, as you likely listen to different music, but we can see our top 10 artists for the past 6 months in an array!

Now let’s update our app to show that data.

Under the Top Artists header we have an unordered list (UL) which includes list items. Instead of manually showing each item, we’re going to map through our artists.

Replace all of the list items in our list with:

{artists.map(artist => {
  return (
    <a key={artist.id} href={artist.external_urls.spotify} className={styles.card}>
      {artist.images[0] && (
        <img width={artist.images[0].width} height={artist.images[0].height} src={artist.images[0].url} alt="" />
      )}
      <h2>{ artist.name }</h2>
    </a>
  );
})}

Here we’re taking our array of artists, mapping through each one, and using the name, Spotify URL, and image to display in the UI.

And once we reload the app, we should see all of our Top Artists!

Album covers for the top 4 artists from my account
My top artists

Now if we scroll down, we’ll still see that we’re seeing a single track for our Top Tracks section, so let’s update that as well.

For our tracks, we’re going to pretty much clone the code we used to request our artists, except swap “artist” for “track”.

Under the artists request add:

const tracksResponse = await fetch(`https://api.spotify.com/v1/me/top/tracks?limit=10`, {
  headers: {
    Authorization: `Bearer ${secrets.spotify.bearerToken}`,
  }
});
const { items: tracks } = await tracksResponse.json();

Then add our new tracks constant to our return statement:

return {
  props: {
    artists,
    tracks
  }
}

Make it available to our component:

export default function Home({ artists, tracks }) {

Then let’s log it out to see the values.

console.log('tracks', tracks);

Once we look in our terminal, we should see our top 10 tracks with similar data included!

Web console showing array of top tracks
Top Tracks data

The biggest difference between the data we used for artists and the data we’re going to use for tracks is we don’t have a top level image.

Instead, we’re going to use the album cover available right inside of the album property.

So under the Top Tracks section in the code, let’s replace all of the list items with the following:

Once the page reloads, we should see our Top Tracks section update with all of our data from Spotify!

List of album covers corresponding to single tracks in Top Tracks list
Top Tracks

Follow along with the commit!

What can we do next?

Add a Now Playing widget

On top of showing your top artists and tracks, show what you’re currently playing in Spotify to help show what’s helping contribute to that list with the Get Currently Playing Track endpoint.

Optimize all of the album cover images

We’re showing a lot of images on our page and that can become expensive in the browser.

Since we’re on Netlify, we can take advantage of easily serving all of those images from Cloudinary using the Cloudinary Netlify Plugin which will automatically optimize our images and serve them in a modern format.

How to Optimize Images on Netlify with the Cloudinary Build Plugin

More fun in Netlify with Puppeteer in serverless functions

Want to play around more with Netlify features? On top of deploying a site, you can build and deploy API endpoints via serverless functions that can perform server-like capabilities.

One example is using Puppeteer to automate Chrome headlessly to do things like scraping a website.

How to Use Puppeteer to Automate Chrome in an API with Netlify Serverless Functions