Next.js Discord

Discord Forum

Fetching own route handler in a client component using SWR doesn't work properly

Unanswered
Saltwater Crocodile posted this in #help-forum
Open in Discord
Saltwater CrocodileOP
// spotify-playing.tsx
"use client"
import useSWR from "swr"
const fetcher = (url) => fetch(url).then((res) => res.json());

export default async function Spotify(){
    const {data, error, isLoading} = useSWR("/api/spotify", fetcher)
    return (
        <div>Now playing: {data.title} </div>
    )
}

// /api/spotify/route
import { currentlyPlayingSong } from "lib/spotify";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const response = await currentlyPlayingSong();

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

  const song = await response.json();

  if (song.item === null) {
    return NextResponse.json({ isPlaying: false }, {status: 200});
  }

  const isPlaying = song.is_playing;
  const title = song.item.name;
  const artist = song.item.artists.map((_artist : {name: string}) => _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 NextResponse.json({
    album,
    albumImageUrl,
    artist,
    isPlaying,
    songUrl,
    title,
  }, {
    status: 200
  });
}

30 Replies

Saltwater CrocodileOP
lib/spotify.ts
const getAccessToken = async () => {
  const refresh_token = process.env.SPOTIFY_REFRESH_TOKEN ? process.env.SPOTIFY_REFRESH_TOKEN : "No refresh Token";


  const response = await fetch("https://accounts.spotify.com/api/token", {
    method: "POST",

    headers: {
      Authorization: `Basic ${Buffer.from(
        `${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`
      ).toString("base64")}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token,
    }),
  });

  return response.json();
};
export const currentlyPlayingSong = async () => {
  const { access_token } = await getAccessToken();

  return fetch("https://api.spotify.com/v1/me/player/currently-playing", {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
};
export default getAccessToken
@maxswjeon Feels like a common question https://nextjs-discord-common-questions.joulev.dev/fetching-own-api-endpoint-in-react-server-components
Saltwater CrocodileOP
that's the thing, I am not fetching in a server component
as you can see above
Sorry, I thought it was a server component because of the async keyword
@joulev > export default async function Spotify client components cannot be async
Saltwater CrocodileOP
alright, first question, I don't want the api to cache the result because the spotify songs change quickly
I know I need to add cache: no-store somewhere but I don't know to which fetch I need to add it to
@Saltwater Crocodile alright, first question, I don't want the api to cache the result because the spotify songs change quickly
or in this fetch
fetch("https://api.spotify.com/v1/me/player/currently-playing", {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
@joulev `export const dynamic = 'force-dynamic'` in your route handler
Saltwater CrocodileOP
alright this fixed the first issue one second I'll right the second issue
@joulev or in this fetch ts fetch("https://api.spotify.com/v1/me/player/currently-playing", { headers: { Authorization: `Bearer ${access_token}`, }, });
Saltwater CrocodileOP
here I removed the async from the client component:
"use client"
import useSWR from "swr"
const fetcher = (url) => fetch(url).then((res) => res.json());

export default function Spotify(){
    const {data, error, isLoading} = useSWR("/api/spotify", fetcher)
    return (
        <div>Now playing: {data.title} </div>
    )
}

but I am getting TypeError: data is undefined, which is weird because when I open /api/spotify in my browser I can see the data that I need, so it seems only this swr step is failing
here you can see I got all the data I need in the route handler
data might be undefined when in loading state
@maxswjeon data might be undefined when in loading state
Saltwater CrocodileOP
That fixed it! tysm, I thought data loading is an optional thing if you want to add it but it seems required I learned my lesson
oooh the spotify data also updates without me refreshing that's really cool, do you know if that's a route handler or SWR feature?
That's the SWR Feature
Saltwater CrocodileOP
cool, well thanks for the help you and joulev, I'll close this now
Saltwater CrocodileOP
looking good
@maxswjeon That's the SWR Feature
Saltwater CrocodileOP
I seem to have a problem
the route handler doesn't update when deployed on vercel
when I am running locally, everything is good, the data is there and updates automatically
Saltwater CrocodileOP
ah figured it out
I didn't update the env variables on vercel
my bad