Building an Apple Music Playlist Creator for Billie Eilish

Using the Apple Music API, MusicKit JS, and Nuxt

Last week Universal Germany and I launched a simple Apple Music web app which allows Billie Eilish fans the ability to create their own playlist of their favorite of her tracks. While developing that app, I shared my struggles with the way the Apple Music API handles playlist sharing. This time I’d like to quickly share a positive take on the Apple Music API and MusicKit JS library. Namely, how easy it is to pull a pool of Billie’s tracks and allow fans to generate playlists from them in a custom web app. I really like this approach because the artist is allowed to control the presentation of the experience and build marketing around it. In the case of our campaign, we chose to tie contesting and data capture into the app.

Unsurprisingly to anyone following my client work lately, I’m using Nuxt.js and Vue.js to develop this web app which is hosted on Netlify. The first thing I did was follow the MusicKit JS configuration instructions so I could easily authenticate Apple Music users and make API calls on their behalf. It then comes down to pulling all of Billie’s tracks, allowing fans to select which of those tracks will make the playlist, and then finally generating the playlist itself. I’m using axios to make my API calls.

Instead of asking Apple Music for all of Billie’s tracks each time the playlist creator is visited, I’m using Nuxt’s generate property to preload that data in a payload that is available to the playlist creation route. So when the site gets built on Netlify, it makes the API calls necessary to pull her tracks and then passes those objects along to the route. Here’s what that might look like in nuxt.config.js.

import axios from 'axios'
export default{
routes: function(callback) {
let apple = axios.create({
baseURL: 'https://api.music.apple.com/v1',
headers: {
'Authorization': 'Bearer YOUR_APPLE_MUSIC_DEVELOPER_TOKEN'
}
}
    // Get all artist album ids from Apple Music
return apple.get('/catalog/us/artists/ARTIST_ID/albums')
.then(res => {
let ids = res.data.data.map(album => album.id)
      // Get all albums (from ids) from Apple Music
return apple.get(`/catalog/us/albums?ids=${ids}`)
.then(res => {
        // Map all tracks from albums into required format
let tracks = [].concat(...res.data.data.map(album => {
return album.relationships.tracks.data.map(track => {
return {
id: track.id,
name: track.attributes.name
}
}
})
})
      callback(null, [{
route: '/',
payload: tracks
}])
})
}
}
Unlike Spotify’s API, Apple Music doesn’t require authentication to access artist, album, and song meta data. All you need is a valid developer token.

We can then access this payload of tracks in the playlist creation component by using the asyncData method to pass the payload directly to our component’s data.

async asyncData({ app, payload, env }) {
if (payload) {
return {
tracks: payload
}
}
}

It’s up to you how you might keep track of user choices but I simply augmented the tracks payload to include a selected boolean which I allowed the user to flip from true and false. I then wrote a computed property which returns an array of selected tracks in the exact format the Apple Music API requires for playlist creation.

computed: {
selected() {
return this.tracks.filter(track => track.selected)
.map(track => {
return {
id: track.id,
type: 'songs'
}
})
}
}

When the fan is ready to create the playlist, give them a big button to click and pass the selected tracks response to the appropriate Apple Music API function using axios. Note that I’m wrapping the call in a MusicKit JS authorize method to make sure the user is logged in before making the call. This will give me access to the user token necessary to create the playlist.

music.authorize()
.then(() => {
let apple = axios.create({
baseURL: 'https://api.music.apple.com/v1',
headers: {
'Authorization': `Bearer YOUR_APPLE_MUSIC_DEVELOPER_TOKEN`,
'Music-User-Token': `MUSIC_USER_TOKEN`
}
})
  apple.post('/me/library/playlists', {
attributes: {
name: 'Billie Eilish',
description: 'Here are my favorite Billie Eilish tracks'
},
relationships: {
tracks: {
data: this.selected
}
}
})
.then(res => {
// successfully created playlist
})
.catch(error => {
// error creating playlist
})
})
.catch(error => {
// error authorizing
})

Pretty simple right? I encourage you to give the Apple Music API and MusicKit JS a chance. The MusicKit JS library has pretty solid web playback functionality which I’ve rolled into Stream. The Apple Music team is also very responsive when you share things socially and provide critical feedback. I’m looking forward to building more with the platform.