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!
my 10/10s
open in spotifymatryoshka
lexycat
1
Unlimited Love
underscores
2
WHITEHORSEMANNEQUIN
Lucy Bedroque
3
keep me going (BIRDBRAIN)
slayr
4
God (with current joys & never goodbye)
matt proxy, Current Joys, never goodbye
5
STARS
matt proxy
6
Burn It
ok, fakemink
7
Trajectory
lapix, Mylta, RANASOL
8
fish in the pool
yeule
9
E7len's Knife
icesawder
10
Music Baby (leroy Remix)
Jane Remover
11
Dyad
Jamie Paige, unit.0
12
Machine Love
Jamie Paige
13
Flashout Freestyle
slayr
14
My Darling, My Companion
Jamie Paige
15
NOGWAPNOLIFE
bleood
16
BIRDBRAIN
Jamie Paige, OK Glass
17
In the dark
venturing
18
Set In Stone
slayr
19
Love Blur
slayr
20
Music Baby
Jane Remover
21
media offline
ariiol
22
SISTERHOOD (LOVE, HER.)
Lucy Bedroque
23
The End
Danny Brown, ta Ukrainka, Zheani, Cynthoni
24
Music and Me
fakemink
25
MIRINAE
TAK, Zekk
26
Rain Capsule
Namitape
27
Overfeel
Namitape
28
All At Once
Ninajirachi
29
Infohazard
Ninajirachi
30
Delete
Ninajirachi
31
weathergirl
FLAVOR FOLEY
32
Lawsyn
ayowitty
33
THUNDRRR
Quadeca
34
THAT'S WHY
Quadeca
35
WAGING WAR
Quadeca, Olēka
36
NO QUESTIONS ASKED
Quadeca
37
Always Have Always Will
Jane Remover
38
SLAM PUNK
Che
39
Akibare
Mylta
40
My life is mine alone! (feat. nenne)
Mylta, nenne
41
disarmed
kumosai, Sayako
42
spectrum
icesawder
43
NOWNEVER
Jaron Steele
44
Pretty Peach
Lucy Bedroque
45
How to Pretend
Lucy Bedroque
46
Knot Me
Lucy Bedroque
47
Sweet Pitcher
Lucy Bedroque
48
Thousand yard stare
kmoe
49
angels in camo
Jane Remover
50
Professional Vengeance
Jane Remover
51
Dreamflasher
Jane Remover
52
Experimental Skin
Jane Remover
53
Psychoboost
Jane Remover, Danny Brown
54
Dancing with your eyes closed
Jane Remover
55
Spider
venturing
56
Believe
venturing
57
alucarda lives!
smiling broadly
58
fake blood recipe
smiling broadly
59
flower bed
defsharp
60
sheaskedwhatmylifeislike
ericdoa
61
Caught up (in circles)
Syzy
62
Pastel Express
Cynax
63
St. Chroma (feat. Daniel Caesar)
Tyler, The Creator, Daniel Caesar
64
let's go home
Jane Remover
65
can you tell?
Jane Remover
66
champ
Jane Remover
67
pretender
Jane Remover
68
kodak moment
Jane Remover
69
movies for guys
Jane Remover
70
misplace
Jane Remover
71
Catch me if you can
tn-shi
72
natural
zeroth
73
mint
Snail's House
74
Emerald Lakeside - Action
はがね, Kitsui Akira
75
back off!!!
Jane Remover, kmoe, juno
76
one more life
Murphmusic, park.
77
Clinozoisite
Ludicin
78
Duhhhhhhhhhhhhhhhhh
underscores
79
Rabbit In The Black Room
Rabbit House
80
String Theocracy - Key Ingredient ver.
Mili
81
My guy (Corporate shuffle)
underscores
82
Wizards
xaev, mopearound
83
Everything Goes On
Porter Robinson, League of Legends
84
phobie d’impulsion
glaive
85
PUSH UR T3MPRR
femtanyl
86
Amethyst Aurora
BilliumMoto
87
the now now and never
what is your name?
88
Reverse Nightmare Tower
bye2
89
pop music
Limonène
90
EXACTLY WHY I'M STILL HERE - TURQUOISEDEATH Remix
bunnyprodge, TURQUOISEDEATH
91
even when the sun is dead, will you tell them how hard i tried
glaive
92
Tojita Sekai
Camellia
93
commatose
glass beach
94
200
glass beach
95
until the dawn breaks
Deathbrain
96
dumb party
Internet Girl
97
skinz
8485
98
Algas Danses
seatrus
99
うみのゆき
seatrus
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.