Skip to main content
RapidDev - Software Development Agency
v0-integrationsNext.js API Route

How to Integrate Spotify API with V0

To use the Spotify API with V0, generate your music UI in V0, then create a Next.js API route at app/api/spotify/route.ts that exchanges OAuth2 tokens and fetches playlists, tracks, or audio features from the Spotify Web API. Store your Client ID and Client Secret in Vercel Dashboard environment variables — never in client-side code.

What you'll learn

  • How to register a Spotify Developer app and get your Client ID and Client Secret
  • How to implement the OAuth2 Authorization Code flow in a Next.js API route
  • How to fetch Spotify playlists, tracks, and user data via a secure server-side route
  • How to store Spotify credentials safely in Vercel environment variables
  • How to build a music player or discovery UI using V0 with Spotify data
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read45 minutesSocialApril 2026RapidDev Engineering Team
TL;DR

To use the Spotify API with V0, generate your music UI in V0, then create a Next.js API route at app/api/spotify/route.ts that exchanges OAuth2 tokens and fetches playlists, tracks, or audio features from the Spotify Web API. Store your Client ID and Client Secret in Vercel Dashboard environment variables — never in client-side code.

Building Music-Powered Apps in V0 with the Spotify API

The Spotify Web API gives your V0 app access to a vast catalog of music data — user playlists, track details, audio features like tempo and energy, artist information, and personalized recommendations. Whether you are building a music discovery tool, a custom playlist manager, or a stats dashboard showing someone's top artists, Spotify's API is the data layer and V0 generates the polished UI on top.

The Spotify API uses OAuth2 for authentication, which means users must log in with their Spotify account and grant your app permission to access their data. This is handled through the Authorization Code flow: your app redirects the user to Spotify's login page, Spotify redirects back to your app with a temporary code, and your server exchanges that code for an access token. All of this exchange happens in your Next.js API routes, never in the browser, so your Client Secret stays private.

For apps that only need public catalog data — searching tracks, browsing albums, fetching public playlists — you can use the simpler Client Credentials flow, which authenticates your app directly without requiring user login. This is ideal for music discovery pages where you just want to search Spotify's library and display results without accessing any personal user data.

Integration method

Next.js API Route

V0 generates the React music UI components while Next.js API routes handle Spotify's OAuth2 token flow and all API calls server-side, keeping your Client Secret out of the browser. The user authenticates with Spotify through a browser redirect, receives an access token, and your API routes use that token to fetch music data on their behalf.

Prerequisites

  • A V0 account with a Next.js project at v0.dev
  • A Spotify account (free or Premium) to create a Developer app
  • A Spotify Developer app registered at developer.spotify.com/dashboard with Client ID and Client Secret
  • A Vercel project connected to your V0 app via GitHub
  • Your Vercel deployment URL for configuring the OAuth redirect URI in Spotify Dashboard

Step-by-step guide

1

Register a Spotify Developer App

Before writing any code, you need to register your application in the Spotify Developer Dashboard. This is how Spotify knows which apps are allowed to access its API and which redirect URIs are permitted for OAuth. Go to developer.spotify.com and log in with your Spotify account. Click on your profile name in the top-right corner and select Dashboard. Then click Create App. Give your app a name (e.g., 'My V0 Music App'), a description, and set the Redirect URI to http://localhost:3000/api/spotify/callback for local development. You will add your production Vercel URL later. Accept the terms and click Save. Once the app is created, you will see your Client ID on the app overview page. Click Show Client Secret to reveal your secret key. Copy both values — you will need them as environment variables. Important: the Client Secret must never appear in client-side code or be committed to your Git repository. Treat it like a password. For production, come back to the Spotify Dashboard after you deploy to Vercel and add your production callback URL (e.g., https://your-project.vercel.app/api/spotify/callback) to the Redirect URIs list. Spotify will reject OAuth callbacks to any URL not on this allowlist, so this step is required before your deployed app can authenticate users.

Pro tip: Add both http://localhost:3000/api/spotify/callback and your production Vercel URL to Redirect URIs from the start — this saves a common debugging session when you deploy.

Expected result: You have a Spotify app in the Developer Dashboard with a Client ID, Client Secret, and at least one redirect URI configured.

2

Generate Your Music UI with V0

With your Spotify app credentials ready, use V0 to generate the front-end components for your music feature. V0 excels at creating visually polished music interfaces — album art grids, track lists, waveform-style progress bars, and artist cards — all styled with Tailwind CSS. When prompting V0, describe exactly what data each component should display and where it fetches that data from. Be specific about the API endpoint paths you plan to create (like /api/spotify/playlists or /api/spotify/search) so V0 wires the fetch calls to the right routes. Also tell V0 to include loading states (skeleton screens) and error states, since music API calls can take a second or two. For the OAuth flow, you also want V0 to generate a Login with Spotify button that redirects to /api/spotify/login — this is the endpoint that will kick off the Authorization Code flow. Once authentication is complete, the user lands back on your app and the music UI can start fetching their data. If you are building a public search feature without user login (Client Credentials flow), you do not need the login button — just the search bar and results display. Ask V0 to generate a search input that posts to /api/spotify/search with a query parameter and renders the results.

V0 Prompt

Create a Spotify music dashboard with a 'Connect with Spotify' button that links to /api/spotify/login. After connecting, show two sections: My Playlists (grid of cards with cover art and playlist name, loaded from /api/spotify/playlists) and Top Tracks This Month (list with rank number, album art thumbnail, track name, and artist, loaded from /api/spotify/top-tracks). Include skeleton loading states for both sections.

Paste this in V0 chat

Pro tip: Ask V0 to use Next.js Image component for album art thumbnails with fixed width and height — Spotify artwork URLs are valid external image sources and Next.js needs them configured in next.config.ts.

Expected result: V0 generates a music dashboard with a Spotify login button and data-loading components that reference your planned API route endpoints.

3

Create the OAuth2 Login and Callback API Routes

The Spotify OAuth2 flow requires two server-side routes: one to redirect the user to Spotify's authorization page, and one to handle the callback and exchange the code for an access token. The login route (app/api/spotify/login/route.ts) builds the Spotify authorization URL with your Client ID, the scopes (permissions) your app needs, and the redirect URI. Scopes are space-separated strings like 'user-read-private user-top-read playlist-read-private'. You redirect the user to this URL and Spotify handles the login form. After the user approves, Spotify sends them back to your callback route (app/api/spotify/callback/route.ts) with a code parameter in the URL. Your callback route exchanges this code for an access token by making a POST request to Spotify's token endpoint. The response includes an access_token (short-lived, 1 hour) and a refresh_token (long-lived). You store these in a secure HTTP-only cookie and redirect the user back to your app's home page. Storing tokens in HTTP-only cookies is the correct security pattern for Next.js — the token never touches client-side JavaScript, preventing XSS attacks from stealing it. When your other API routes need to call Spotify, they read the token from the cookie using the cookies() function from next/headers. For apps not requiring user authentication (public search only), you skip these two routes entirely and instead fetch a Client Credentials token directly in your search route using your Client ID and Secret with a basic auth header.

V0 Prompt

Create two Next.js API routes: app/api/spotify/login/route.ts that redirects to Spotify's authorization URL with scopes 'user-read-private user-top-read playlist-read-private user-read-recently-played', and app/api/spotify/callback/route.ts that exchanges the code parameter for tokens via POST to https://accounts.spotify.com/api/token and stores the access_token in an HTTP-only cookie. Use process.env.SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, and SPOTIFY_REDIRECT_URI.

Paste this in V0 chat

app/api/spotify/login/route.ts
1// app/api/spotify/login/route.ts
2import { NextResponse } from 'next/server';
3
4export async function GET() {
5 const scopes = [
6 'user-read-private',
7 'user-top-read',
8 'playlist-read-private',
9 'user-read-recently-played',
10 ].join(' ');
11
12 const params = new URLSearchParams({
13 response_type: 'code',
14 client_id: process.env.SPOTIFY_CLIENT_ID!,
15 scope: scopes,
16 redirect_uri: process.env.SPOTIFY_REDIRECT_URI!,
17 });
18
19 return NextResponse.redirect(
20 `https://accounts.spotify.com/authorize?${params.toString()}`
21 );
22}

Pro tip: Only request the Spotify scopes your app actually needs. Requesting unnecessary permissions increases the chance users decline the authorization prompt.

Expected result: Clicking the 'Connect with Spotify' button redirects to Spotify's login page. After approving, Spotify redirects back to your callback route and the user lands on your dashboard.

4

Create the Data-Fetching API Route

With authentication working, create the API routes that fetch music data from Spotify and return it to your V0-generated components. Each route reads the access token from the HTTP-only cookie set during OAuth, then calls the appropriate Spotify Web API endpoint. For example, to fetch the current user's playlists, your route reads the token from cookies, then calls GET https://api.spotify.com/v1/me/playlists with an Authorization: Bearer TOKEN header. The Spotify API returns a JSON object with an items array of playlist objects, each containing the playlist name, description, cover image, and track count. For top tracks and artists, the endpoint is https://api.spotify.com/v1/me/top/tracks (or /artists) with a time_range query parameter (short_term = 4 weeks, medium_term = 6 months, long_term = all time). For recently played tracks it is https://api.spotify.com/v1/me/player/recently-played. Handle token expiration gracefully: if Spotify returns a 401 Unauthorized response, the access token has expired and you need to use the refresh token to get a new one. You can add a helper function that calls POST https://accounts.spotify.com/api/token with the refresh token and your client credentials, then updates the cookie with the new access token and retries the original request. Return only the data your components need — do not pass the entire Spotify response object. Extract just the fields like name, images, artists, and external_urls to keep your API responses lean and your components simple.

V0 Prompt

Create a Next.js API route at app/api/spotify/playlists/route.ts that reads the spotify_access_token from cookies, calls GET https://api.spotify.com/v1/me/playlists with limit=20, and returns an array of objects with id, name, images, and tracks.total fields. If the response is 401, return status 401 so the client can redirect to /api/spotify/login.

Paste this in V0 chat

app/api/spotify/playlists/route.ts
1// app/api/spotify/playlists/route.ts
2import { NextResponse } from 'next/server';
3import { cookies } from 'next/headers';
4
5export async function GET() {
6 const cookieStore = await cookies();
7 const accessToken = cookieStore.get('spotify_access_token')?.value;
8
9 if (!accessToken) {
10 return NextResponse.json({ error: 'Not authenticated' }, { status: 401 });
11 }
12
13 const response = await fetch(
14 'https://api.spotify.com/v1/me/playlists?limit=20',
15 {
16 headers: {
17 Authorization: `Bearer ${accessToken}`,
18 },
19 }
20 );
21
22 if (response.status === 401) {
23 return NextResponse.json({ error: 'Token expired' }, { status: 401 });
24 }
25
26 if (!response.ok) {
27 return NextResponse.json(
28 { error: 'Failed to fetch playlists' },
29 { status: response.status }
30 );
31 }
32
33 const data = await response.json();
34 const playlists = data.items.map((p: any) => ({
35 id: p.id,
36 name: p.name,
37 images: p.images,
38 trackCount: p.tracks.total,
39 externalUrl: p.external_urls.spotify,
40 }));
41
42 return NextResponse.json({ playlists });
43}

Pro tip: Add next.config.ts image domain configuration for i.scdn.co (Spotify's CDN) to allow Next.js Image component to load album artwork.

Expected result: Calling /api/spotify/playlists returns a JSON array of the authenticated user's playlists with name, cover art, and track count.

5

Add Environment Variables in Vercel

Your Spotify API routes read three environment variables: SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, and SPOTIFY_REDIRECT_URI. These must be added to Vercel's environment configuration so they are available when your serverless functions run. Open your Vercel Dashboard, select your project, click the Settings tab, then Environment Variables in the left sidebar. Add each variable with its value and set the environment scope to Production, Preview, and Development. SPOTIFY_CLIENT_ID: your app's Client ID from the Spotify Developer Dashboard. This is not a secret — it appears in OAuth URLs that users can see — but adding it as an environment variable keeps your code flexible. SPOTIFY_CLIENT_SECRET: your app's Client Secret. This MUST be kept server-side only. Never add the NEXT_PUBLIC_ prefix to this variable. If this leaks, anyone can make API calls as your app. SPOTIFY_REDIRECT_URI: for production, set this to https://your-project.vercel.app/api/spotify/callback. This must exactly match one of the redirect URIs you registered in the Spotify Developer Dashboard — even a trailing slash difference will cause an OAuth error. For local development, create a .env.local file with the same variables set to their development values (http://localhost:3000/api/spotify/callback for the redirect URI). Vercel does not read .env files during deployment, so the Vercel Dashboard variables are the only source for production. After adding variables, trigger a redeployment by pushing a commit to GitHub. Then go back to the Spotify Developer Dashboard and add your production callback URL to the app's Redirect URIs list.

Pro tip: Use Vercel's Preview environment with a separate Spotify app (or the same app with your preview URL added) to test OAuth flows on preview deployments before going to production.

Expected result: Vercel shows all three Spotify environment variables saved. Redeployment succeeds and the OAuth login flow works on your production URL.

Common use cases

Personal Listening Stats Dashboard

A developer builds a dashboard showing their top artists, top tracks, and recently played songs. V0 generates the card-based UI layout with album art thumbnails and play counts. The Next.js API routes fetch the user's listening data from Spotify's personalization endpoints after OAuth login.

V0 Prompt

Create a music stats dashboard with three sections: Top Artists (grid of 6 artist cards with photo and name), Top Tracks (list of 10 tracks with album art, title, artist), and Recently Played (list of 5 with timestamp). Each section has a tab for short_term, medium_term, and long_term. Data loads from /api/spotify/top-items.

Copy this prompt to try it in V0

Playlist Browser and Manager

A user wants to browse all their Spotify playlists in a cleaner interface than the Spotify app. V0 generates a sidebar playlist list with a track listing panel. API routes fetch the user's playlists and the tracks in each playlist on demand.

V0 Prompt

Build a two-panel playlist manager. Left panel: scrollable list of playlists with cover art and track count, loaded from /api/spotify/playlists. Right panel: track listing for the selected playlist from /api/spotify/playlist-tracks?id=PLAYLIST_ID. Include a search input to filter tracks by name.

Copy this prompt to try it in V0

Music Discovery Search Page

A music blog embeds a Spotify search widget so readers can search for any song, artist, or album and see results with Spotify preview links. No user login required — it uses the Client Credentials flow for public catalog access.

V0 Prompt

Create a music search page with a search bar at the top. When the user types and presses Enter, fetch results from /api/spotify/search?q=QUERY and display track cards with album art, track name, artist name, and an external link to open the track in Spotify. Show a loading skeleton while fetching.

Copy this prompt to try it in V0

Troubleshooting

INVALID_CLIENT error on the Spotify authorization page

Cause: The Client ID in your environment variable does not match the Spotify app, or the app has been deleted or suspended.

Solution: Open Spotify Developer Dashboard, find your app, and copy the exact Client ID. Compare it character by character with your SPOTIFY_CLIENT_ID environment variable in Vercel. Redeploy after fixing.

INVALID_REDIRECT_URI error after Spotify login

Cause: The SPOTIFY_REDIRECT_URI in your environment does not exactly match one of the redirect URIs registered in the Spotify Developer Dashboard.

Solution: Go to Spotify Developer Dashboard → your app → Edit. Add the exact URL from your SPOTIFY_REDIRECT_URI env variable to the Redirect URIs list. Both http and https versions are treated as different URIs.

API route returns 401 after user successfully logged in

Cause: The Spotify access token stored in the cookie has expired. Tokens last 1 hour.

Solution: Implement a token refresh flow using the refresh_token stored in a second cookie. When a 401 response is received, POST to https://accounts.spotify.com/api/token with grant_type=refresh_token and your client credentials to get a new access token.

typescript
1const refreshResponse = await fetch('https://accounts.spotify.com/api/token', {
2 method: 'POST',
3 headers: {
4 'Content-Type': 'application/x-www-form-urlencoded',
5 Authorization: `Basic ${Buffer.from(`${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`).toString('base64')}`,
6 },
7 body: new URLSearchParams({
8 grant_type: 'refresh_token',
9 refresh_token: refreshToken,
10 }),
11});

Next.js Image component throws error loading Spotify album artwork

Cause: Next.js blocks external images from domains not listed in next.config.ts for security reasons.

Solution: Add Spotify's image CDN domain to your Next.js configuration in next.config.ts.

typescript
1// next.config.ts
2const nextConfig = {
3 images: {
4 remotePatterns: [
5 { protocol: 'https', hostname: 'i.scdn.co' },
6 { protocol: 'https', hostname: 'mosaic.scdn.co' },
7 ],
8 },
9};
10export default nextConfig;

Best practices

  • Store only the access token and refresh token in cookies — never log or expose them in API responses
  • Request only the Spotify OAuth scopes your app genuinely needs; additional scopes reduce user trust
  • Cache Spotify responses for public data (track info, artist data) using Next.js fetch caching to reduce API calls and stay within rate limits
  • Handle Spotify's 429 rate limit responses by checking the Retry-After header and implementing exponential backoff
  • Validate that the state parameter matches in the OAuth callback to prevent CSRF attacks
  • Use NEXT_PUBLIC_SPOTIFY_CLIENT_ID only if you need it in client-side code (e.g., for Spotify's Web Playback SDK) — otherwise keep it server-side only
  • Test your OAuth flow in an incognito window to simulate new user authentication without cached tokens

Alternatives

Frequently asked questions

Does the Spotify API require a Premium account?

Most Spotify Web API endpoints work with a free Spotify account. However, the Web Playback SDK (for streaming audio directly in your app) requires the user to have a Spotify Premium account. Read-only data endpoints like playlists, top tracks, and search work for all users.

Can I use the Spotify API without making users log in?

Yes — for public catalog data like searching tracks, albums, and artists, use the Client Credentials flow. Your server exchanges your Client ID and Secret for a short-lived app token (not user-specific) and uses that token for public endpoint calls. This does not require any user interaction or OAuth redirect.

Why do I need a server-side API route instead of calling Spotify from the browser?

Your Spotify Client Secret must never appear in browser-accessible JavaScript — if it did, anyone who views your page source could steal it and make API calls as your app. Next.js API routes run on Vercel's servers and keep the secret out of the browser's JavaScript bundle entirely.

How do I add Spotify's Web Playback SDK to a V0 app?

Load the Spotify Web Playback SDK script (https://sdk.scdn.co/spotify-player.js) in your Next.js layout or a client component using useEffect. The SDK requires a Premium user account and an access token with the streaming scope. Ask V0 to generate the player UI component, then wire it to the SDK's Player class in a useEffect hook.

What happens when the Spotify access token expires?

Spotify access tokens expire after 1 hour. Your API routes should detect 401 responses from Spotify and automatically use the stored refresh token to request a new access token from https://accounts.spotify.com/api/token. Store the new access token in the cookie and retry the original request transparently.

Is there a rate limit on the Spotify API?

Yes. Spotify enforces rate limits that vary by endpoint. If you exceed them, you receive a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait. For public-facing apps with many users, implement server-side caching for non-user-specific data like search results and track information.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.