hi this is my first blog post! i suck at writing anything down anything so hopefully talking about random things helps.
this all started when i wanted to display my favorite songs on my /about page, i already have a spotify playlist of them so i could just use the official embed. the problem is that the embed loads 1.96 mb of minified javascript.
…and also makes tons of strange requests back to spotify, is extremely loud (with no volume slider!), and preloads some songs. on my old site i just gave in and used the official embed, but after seeing that scraping spotify embeds was possible (thanks l-m!), i tried making my own.
all of that javascript is even more insane considering this was meant to be used on other sites, you’d think the multi-billion $ company would care about performance for a simple embed. but it’s no secret that a lot of the web is getting megabytes of javascript larger, from complex frameworks and overkill libraries just to render mostly static sites. tonsky already has a great article on this.
here they are!
extremely good songs
open in spotifyDyad
Jamie Paige, unit.0
1
Machine Love
Jamie Paige
2
Flashout Freestyle
slayr
3
My Darling, My Companion
Jamie Paige
4
NOGWAPNOLIFE
bleood
5
BIRDBRAIN
Jamie Paige, OK Glass
6
In the dark
venturing
7
Set In Stone
slayr
8
Love Blur
slayr
9
Music Baby
Jane Remover
10
media offline
ariiol
11
The End
Danny Brown, ta Ukrainka, Zheani, Cynthoni
12
Music and Me
fakemink
13
MIRINAE
TAK, Zekk
14
Rain Capsule
Namitape
15
Overfeel
Namitape
16
All At Once
Ninajirachi
17
Infohazard
Ninajirachi
18
Delete
Ninajirachi
19
weathergirl
FLAVOR FOLEY
20
Lawsyn
ayowitty
21
THUNDRRR
Quadeca
22
THAT'S WHY
Quadeca
23
WAGING WAR
Quadeca, Olēka
24
NO QUESTIONS ASKED
Quadeca
25
Always Have Always Will
Jane Remover
26
SLAM PUNK
Che
27
Akibare
Mylta
28
My life is mine alone! (feat. nenne)
Mylta, nenne
29
disarmed
kumosai, Sayako
30
spectrum
icesawder
31
NOWNEVER
Jaron
32
Pretty Peach
Lucy Bedroque
33
How to Pretend
Lucy Bedroque
34
Knot Me
Lucy Bedroque
35
Sweet Pitcher
Lucy Bedroque
36
Thousand yard stare
kmoe
37
angels in camo
Jane Remover
38
Professional Vengeance
Jane Remover
39
Dreamflasher
Jane Remover
40
Experimental Skin
Jane Remover
41
Psychoboost
Jane Remover, Danny Brown
42
Dancing with your eyes closed
Jane Remover
43
Spider
venturing
44
Believe
venturing
45
alucarda lives!
smiling broadly
46
fake blood recipe
smiling broadly
47
flower bed
defsharp
48
sheaskedwhatmylifeislike
ericdoa
49
Caught up (in circles)
Syzy
50
Pastel Express
Cynax
51
St. Chroma (feat. Daniel Caesar)
Tyler, The Creator, Daniel Caesar
52
let's go home
Jane Remover
53
can you tell?
Jane Remover
54
champ
Jane Remover
55
pretender
Jane Remover
56
kodak moment
Jane Remover
57
movies for guys
Jane Remover
58
misplace
Jane Remover
59
Catch me if you can
tn-shi
60
natural
zeroth
61
mint
Snail's House
62
Emerald Lakeside - Action
はがね, Kitsui Akira
63
back off!!!
Jane Remover, kmoe, juno
64
one more life
Murphmusic, park.
65
Clinozoisite
Ludicin
66
Duhhhhhhhhhhhhhhhhh
underscores
67
Rabbit In The Black Room
Rabbit House
68
String Theocracy - Key Ingredient ver.
Mili
69
My guy (Corporate shuffle)
underscores
70
Wizards
xaev, mopearound
71
Everything Goes On
Porter Robinson, League of Legends
72
phobie d’impulsion
glaive
73
PUSH UR T3MPRR
femtanyl
74
Amethyst Aurora
BilliumMoto
75
the now now and never
what is your name?
76
Reverse Nightmare Tower
bye2
77
pop music
Limonène
78
EXACTLY WHY I'M STILL HERE - TURQUOISEDEATH Remix
bunnyprodge, TURQUOISEDEATH
79
even when the sun is dead, will you tell them how hard i tried
glaive
80
Tojita Sekai
Camellia
81
commatose
glass beach
82
200
glass beach
83
until the dawn breaks
Deathbrain
84
dumb party
Internet Girl
85
skinz
8485
86
Algas Danses
seatrus
87
うみのゆき
seatrus
88
Palmy Flakes
seatrus
89
Cloud99 (As Above Mix)
Machine Girl
90
enchanted love
linear ring
91
Midnight Theater
Kano, Nagi Nemoto
92
Mola mola
Marmalade butcher
93
Another Ride
ippo.tsk, Synthesizer V ANRI
94
neon glow
glass beach
95
I Still Miss You
bo en, Tomggg
96
(We Are) Friends
bo en, Winamp Boys
97
Our Time
bo en, PAS TASTA
98
Kansoku-eisei
Nanahira, Camellia
99
GURUGURU
Snail's House
100
there's more songs on spotify :)
the track embed was made with 0 JS, and the playlist embed was made with 1.84kb (minified) of JS, that’s 99.9061% smaller than the official embed, and i think it fits my site much better :)
ill get the playlist volume slider done one of these days… (9/14/2024: done!)
how
first, you can just make a fetch request to the normal embed url (either for a song or playlist) pretending to be a browser
const res = await fetch(
`https://open.spotify.com/embed/playlist/2m2lebj9Lg6Riwfyv7G9AD`,
{
headers: {
"User-Agent":
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
Pragma: "no-cache",
"Cache-Control": "no-cache",
},
method: "GET",
},
);
const html = await res.text();
and in the html response you get back, at the end there’s a magical script tag with the id __NEXT_DATA__ that contains everything you need!

const json = html.substring(
html.lastIndexOf(`type="application/json">`) +
`type="application/json">`.length,
html.lastIndexOf(`</script>`),
);
const data: PlaylistEmbedData = JSON.parse(json);
you can make whatever with this data now! i’d highly recommend caching it. you can cache song embed data much more aggressively than playlists cause those shouldn’t change.
it’s possible to make your embeds use 0 JS by using the native <audio /> element, which is what i do for singular song embeds. there’s a pretty big problem when using <audio /> for each song in a playlist embed though, it might take safari 8 seconds to load your site sometimes (not an exaggeration).
yes i did pinpoint the loading times to the hundred <audio /> elements, safari really doesn’t like that rendering that many…
note that you can barely style <audio /> elements and the element looks very different across each browser. because of all that i used a bit of JS with web components for my playlist embed, which gets server side rendered with astro.