Deezer offers a rich API that provides access to music charts from various countries via playlist endpoints. In this article, you'll learn how to build a fun music chart website using it. Whether you're looking to polish your frontend skills or tackle common issues like CORS errors, this project has you covered.

Charts Online demo
Charts Online demo

Link to the demo: https://charts.corsfix.com

Understanding the CORS Challenge

When you try to call the Deezer API directly from your frontend (e.g., fetching a playlist like https://api.deezer.com/playlist/3155776842), you might run into a CORS error. This happens because Deezer doesn’t return the appropriate CORS headers for direct browser access from different origins, so your browser blocks the response for security reasons.

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

CORS Error when calling Deezer API directly

The Workaround: Using a CORS Proxy

To keep things simple and avoid setting up your own backend, you can use a CORS proxy. A CORS proxy fetches the API data on your behalf (from Deezer, in this case) and sends it back to your frontend with the correct CORS headers. This lets your app access the data without any hassle.

fetch("https://proxy.corsfix.com/?");

Using CORS proxy to fetch Deezer data

Setting Up Your Project

For this project, we'll be using Next.js with the static export mode. This approach helps us deploy your project on any static hosting service (like GitHub Pages, Cloudflare Pages, Netlify, or Firebase Hosting) without needing a dedicated Node.js server.

What Your App Needs to Do

  1. Fetch Deezer Chart Data: Retrieve playlist data (representing a country's chart) from the Deezer API via a CORS proxy and store it in your component state.
  2. Create a Country Selector: Allow users to choose a country, which maps to a specific Deezer playlist ID.
  3. Display the Chart: Render the list of songs, including title, artist, album art, and duration.
  4. (Optional) Add Audio Previews: Implement functionality to play short audio previews provided by the Deezer API.

Now let’s dive into each of these steps.

Building the App

1. Fetching the Deezer API

Directly calling the Deezer API from your frontend leads to CORS issues. To work around this, we’ll use a CORS proxy in your fetch request. You'll need the specific playlist ID for the chart you want to display (e.g., 3155776842 for the Worldwide chart).

// Example fetch using a CORS proxy for Deezer Worldwide Chart
fetch("https://proxy.corsfix.com/?https://api.deezer.com/playlist/3155776842")
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then((data) => {
    // Store the track data (data.tracks.data) in state
    console.log(data.tracks.data);
  })
  .catch((err) => console.error("Error fetching the Deezer API:", err));

2. Creating a Country Selector

Deezer uses specific playlist IDs for different country charts. You'll need a way to map user-friendly country names to these IDs. You can store this mapping in a constant array or object.

// Simplified example of country data
const countries = [
  { name: "Worldwide", flag: "🌐", id: 3155776842 },
  { name: "United States", flag: "🇺🇸", id: 1313621735 },
  // ... more countries
];

// In your component state
const [selectedCountryId, setSelectedCountryId] = useState(countries[0].id);

// Function to update the chart when a country is selected
const handleCountryChange = (newCountryId) => {
  setSelectedCountryId(newCountryId);
  // Trigger API fetch with the newCountryId
};

You can then use a dropdown or a similar UI element to let users select a country, triggering handleCountryChange.

3. Displaying the Chart Data

Once you have the track data in your component's state, you can map over it to render the chart list. Remember to handle loading and error states gracefully.

// Simplified JSX structure for displaying songs
{
  isLoading ? (
    <p>Loading...p>
  ) : error ? (
    <p>Error: {error}p>
  ) : (
    <ul>
      {songs.map((song, index) => (
        <li key={song.id}>
          <span>{index + 1}span>
          <img src={song.album.cover_small} alt={song.album.title} />
          <div>
            <p>{song.title_short}p>
            <p>{song.artist.name}p>
          div>
          <span>{formatDuration(song.duration)}span>
        li>
      ))}
    ul>
  );
}

This structure displays the rank, album art, title, artist, and duration for each song.

4. (Optional) Adding Audio Previews

Deezer API responses often include a preview URL for each track. You can add a play/pause button to let users listen to these snippets using the HTML element.

// State to track the currently playing audio
const [playingPreviewUrl, setPlayingPreviewUrl] = useState(null);
const audioRef = useRef(null); // To control the audio element

function handlePlayPause(previewUrl) {
  if (audioRef.current && playingPreviewUrl === previewUrl) {
    // Pause current track
    audioRef.current.pause();
    setPlayingPreviewUrl(null);
  } else {
    // Stop previous track if any
    if (audioRef.current) {
      audioRef.current.pause();
    }
    // Play new track
    audioRef.current = new Audio(previewUrl);
    audioRef.current.play();
    setPlayingPreviewUrl(previewUrl);
    // Reset when finished
    audioRef.current.onended = () => setPlayingPreviewUrl(null);
  }
}

// Add a button to your song list item
<button onClick={() => handlePlayPause(song.preview)}>
  {playingPreviewUrl === song.preview ? "Pause" : "Play"}
</button>;

This provides an interactive element to your chart application.

Conclusion

You’ve now built a music chart website that leverages the Deezer API and effectively handles common frontend hurdles like CORS errors. You learned how to overcome these issues with a CORS proxy, implement a country selector using Deezer playlist IDs, display chart data cleanly, and optionally add audio previews for an interactive experience.

If you are looking for a reliable CORS proxy to handle API requests in your frontend projects, give Corsfix a try! It's free to get started, and you only upgrade when you need production-level features.

Happy coding!

Demo: https://charts.corsfix.com
Code: https://github.com/corsfix/charts