Index: src/assets/js/shared/post-music-type.js
===================================================================
--- src/assets/js/shared/post-music-type.js	(revision b406d25e8f0b0b49e6c45df1a3281e46425ca139)
+++ src/assets/js/shared/post-music-type.js	(revision 25dd08f3833da4deb81ef7a027a7e4382dbc5181)
@@ -21,5 +21,9 @@
  *   een collectie                 -> die soort  metadata van de post geleend
  *   een collectie + losse tracks  -> album      de losse zijn BONUS-TRACKS
+ *   een MIXTAPE + losse tracks    -> mixtape    de losse zijn BONUS-TRACKS
  *   twee of meer collecties       -> post       NIETS geleend
+ *
+ * Die vierde regel is de uitzondering op de derde en staat er met opzet naast:
+ * bonustracks maken van een uitgave een album, maar een bandje is geen uitgave.
  *
  * Waarom de lening bij de laatste vervalt: die bestaat omdat een collectie soms
@@ -39,4 +43,14 @@
 // insluit, telt hier niet mee. Anders zou een shortcode die niets oplevert wel
 // het type van de post kunnen bepalen.
+// De soorten die een playlist kan zijn, en dit is de ENIGE lijst. PlaylistService
+// en music/index.js halen hem hier op, precies omdat het andersom niet kan:
+// deze module draait ook in de browser en mag niets van de database weten.
+//
+// Waarom dat uitmaakt: bij twee soorten stond de keuze vijf keer als
+// `x === 'playlist' ? 'playlist' : 'album'` verspreid over drie bestanden. Zo'n
+// vorm valt niet om bij een derde soort, hij slikt hem -- een mixtape werd
+// stilzwijgend een album en ging als Album de deur uit.
+export const SOORTEN = ['album', 'playlist', 'mixtape'];
+
 const RE_PLAYLIST = /\[\[playlist:([a-z0-9][a-z0-9-]*)\]\]/gi;
 const RE_ALBUM    = /\[\[album:([^\]]+)\]\]/g;
@@ -64,5 +78,5 @@
   const uitPlaylists = playlists.map((id) => {
     const kind = zoek(id);
-    if (kind !== 'album' && kind !== 'playlist') { onbekend.push(id); return null; }
+    if (!SOORTEN.includes(kind)) { onbekend.push(id); return null; }
     return { soort: kind, id };
   }).filter(Boolean);
@@ -87,4 +101,14 @@
   if (collecties.length === 1) {
     const c0 = collecties[0];
+    // EEN MIXTAPE BLIJFT EEN MIXTAPE, ook met losse tracks erbij. De regel
+    // hieronder maakt van collectie + losse tracks een album met bonustracks, en
+    // dat klopt voor een uitgave: extra nummers bij een plaat zijn bonus. Een
+    // bandje is geen uitgave. Er een album van maken omdat er een los nummer
+    // naast staat zou het ding hernoemen op grond van iets wat er niet bij
+    // hoort. Album en playlist houden bewust hun oude gedrag: dat zijn
+    // bestaande posts en die mogen hier niet stilletjes van soort wisselen.
+    if (c0.soort === 'mixtape') {
+      return { type: 'mixtape', collectie: c0, tracks: [], bonus: tracks, leentMetadata: true };
+    }
     // Losse tracks naast een collectie zijn geen rommelrestje maar bonus-tracks,
     // en dat maakt het geheel een album.
