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 spotifyMusic and Me
fakemink
1
MIRINAE
TAK, Zekk
2
Rain Capsule
Namitape
3
Overfeel
Namitape
4
All At Once
Ninajirachi
5
Infohazard
Ninajirachi
6
Delete
Ninajirachi
7
I Was Meant To Die Like This
kuru
8
weathergirl
FLAVOR FOLEY
9
Lawsyn
ayowitty
10
THUNDRRR
Quadeca
11
THAT'S WHY
Quadeca
12
WAGING WAR
Quadeca, Olēka
13
NO QUESTIONS ASKED
Quadeca
14
Always Have Always Will
Jane Remover
15
SLAM PUNK
Che
16
Akibare
Mylta
17
My life is mine alone! (feat. nenne)
Mylta, nenne
18
disarmed
kumosai, Sayako
19
spectrum
icesawder
20
NOWNEVER
Jaron
21
How to Pretend
Lucy Bedroque
22
Knot Me
Lucy Bedroque
23
Sweet Pitcher
Lucy Bedroque
24
Thousand yard stare
kmoe
25
angels in camo
Jane Remover
26
Professional Vengeance
Jane Remover
27
Dreamflasher
Jane Remover
28
Experimental Skin
Jane Remover
29
Psychoboost feat danny brown
Jane Remover, Danny Brown
30
Dancing with your eyes closed
Jane Remover
31
Spider
venturing
32
Believe
venturing
33
alucarda lives!
smiling broadly
34
fake blood recipe
smiling broadly
35
flower bed
defsharp
36
sheaskedwhatmylifeislike
ericdoa
37
Caught up (in circles)
Syzy
38
Pastel Express
Cynax
39
St. Chroma (feat. Daniel Caesar)
Tyler, The Creator, Daniel Caesar
40
let's go home
Jane Remover
41
can you tell?
Jane Remover
42
champ
Jane Remover
43
pretender
Jane Remover
44
kodak moment
Jane Remover
45
movies for guys
Jane Remover
46
misplace
Jane Remover
47
Catch me if you can
tn-shi
48
natural
zeroth
49
mint
Snail's House
50
Emerald Lakeside - Action
はがね, Kitsui Akira
51
back off!!!
Jane Remover, kmoe, juno
52
one more life
Murphmusic, park.
53
Clinozoisite
Ludicin
54
Duhhhhhhhhhhhhhhhhh
underscores
55
Rabbit In The Black Room
Rabbit House
56
String Theocracy - Key Ingredient ver.
Mili
57
My guy (Corporate shuffle)
underscores
58
Wizards
xaev, mopearound
59
Everything Goes On
Porter Robinson, League of Legends
60
phobie d’impulsion
glaive
61
PUSH UR T3MPRR
femtanyl
62
Amethyst Aurora
BilliumMoto
63
the now now and never
what is your name?
64
Reverse Nightmare Tower
bye2
65
pop music
Limonène
66
EXACTLY WHY I'M STILL HERE - TURQUOISEDEATH Remix
bunnyprodge, TURQUOISEDEATH
67
even when the sun is dead, will you tell them how hard i tried
glaive
68
Tojita Sekai
Camellia
69
commatose
glass beach
70
200
glass beach
71
until the dawn breaks
Deathbrain
72
dumb party
Internet Girl
73
skinz
8485
74
Algas Danses
seatrus
75
うみのゆき
seatrus
76
Palmy Flakes
seatrus
77
Cloud99 (As Above Mix)
Machine Girl
78
enchanted love
linear ring
79
Midnight Theater
Kano, Nagi Nemoto
80
Mola mola
Marmalade butcher
81
Another Ride
ippo.tsk, Synthesizer V ANRI
82
neon glow
glass beach
83
I Still Miss You
bo en, Tomggg
84
(We Are) Friends
bo en, Winamp Boys
85
Our Time
bo en, PAS TASTA
86
Kansoku-eisei
Nanahira, Camellia
87
GURUGURU
Snail's House
88
About 10 Hours of Doubting Myself
Yem
89
GHOST OF LORELEY
lasah
90
awesome ends with ME and ugly starts with U
c0ncernn
91
DILF repellent
c0ncernn
92
タイニーリトル・アジアンタム
ShibayanRecords
93
lastnaut
Sleeping Pola
94
NekovhParavh
Sad Keyboard Guy, Gardens
95
cool delusions about morphing into a cat
crxw
96
Blooming Afternoon
ミツキヨ
97
you're Nxt -Dreams Remix- (feat. MisoilePunch)
uma, Morimori Atsushi, MisoilePunch♪
98
Tenebre Rosso Sangue (ULTRAKILL Original Game Soundtrack)
Keygen Church
99
Altars of Apostasy
Heaven Pierce Her
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.