MediaPlaylist
note

This rune is part of @refrakt-md/media. Install with npm install @refrakt-md/media and add "@refrakt-md/media" to the plugins array in your refrakt.config.json.

Playlist

Curated track listings for albums, podcasts, audiobooks, and mixes. A heading becomes the playlist title, an image becomes the cover art, a paragraph becomes the description, and a list becomes the track listing. Bold text in each list item is the track name, parenthetical text is the duration, and italic text is the per-track artist.

Basic usage

An album with an artist and track listing.

{% playlist type="album" artist="Pink Floyd" media-position="start" %}
![The Dark Side of the Moon](https://assets.refrakt.md/playlist-dark-side-of-the-moon.png)

---

# The Dark Side of the Moon

A landmark progressive rock album exploring themes of time, death, and madness.

- **Speak to Me** (1:13)
- **Breathe** (2:43)
- **On the Run** (3:36)
- **Time** (7:05)
- **The Great Gig in the Sky** (4:44)
{% /playlist %}
<section data-field="content-section" data-rune="playlist" typeof="MusicPlaylist" data-rune-fields="{&quot;type&quot;:&quot;album&quot;,&quot;media-position&quot;:&quot;start&quot;,&quot;artist&quot;:&quot;Pink Floyd&quot;}">
  <meta content="Pink Floyd" property="byArtist">
  <div data-name="media">
    <img src="https://assets.refrakt.md/playlist-dark-side-of-the-moon.png" alt="The Dark Side of the Moon" property="image">
  </div>
  <h1 id="the-dark-side-of-the-moon" data-name="headline" property="name">The Dark Side of the Moon</h1>
  <p data-name="blurb">A landmark progressive rock album exploring themes of time, death, and madness.</p>
  <ol data-name="tracks">
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Speak to Me</span>
      <span data-name="track-artist" property="byArtist">Pink Floyd</span>
      <span data-name="track-duration">1:13</span>
      <meta property="duration" content="PT73S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Breathe</span>
      <span data-name="track-artist" property="byArtist">Pink Floyd</span>
      <span data-name="track-duration">2:43</span>
      <meta property="duration" content="PT163S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">On the Run</span>
      <span data-name="track-artist" property="byArtist">Pink Floyd</span>
      <span data-name="track-duration">3:36</span>
      <meta property="duration" content="PT216S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Time</span>
      <span data-name="track-artist" property="byArtist">Pink Floyd</span>
      <span data-name="track-duration">7:05</span>
      <meta property="duration" content="PT425S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">The Great Gig in the Sky</span>
      <span data-name="track-artist" property="byArtist">Pink Floyd</span>
      <span data-name="track-duration">4:44</span>
      <meta property="duration" content="PT284S">
    </li>
  </ol>
</section>
The Dark Side of the Moon
album

The Dark Side of the Moon

A landmark progressive rock album exploring themes of time, death, and madness.

  1. Speak to MePink Floyd1:13
  2. BreathePink Floyd2:43
  3. On the RunPink Floyd3:36
  4. TimePink Floyd7:05
  5. The Great Gig in the SkyPink Floyd4:44
<section data-field="content-section" typeof="MusicPlaylist" class="rf-playlist rf-playlist--album" data-type="album" data-media-position="start" data-artist="Pink Floyd" data-rune="playlist" data-density="full">
  <div data-name="media" class="rf-playlist__media" data-section="media" data-media="cover">
    <img src="https://assets.refrakt.md/playlist-dark-side-of-the-moon.png" alt="The Dark Side of the Moon" property="image" />
  </div>
  <div data-name="content" class="rf-playlist__content">
    <div data-name="eyebrow" data-zone="eyebrow" data-zone-layout="bar" class="rf-playlist__eyebrow">
      <span class="rf-badge" data-meta-type="category">album</span>
    </div>
    <header data-name="preamble" class="rf-playlist__preamble" data-section="preamble">
      <h1 id="the-dark-side-of-the-moon" data-name="headline" property="name" class="rf-playlist__headline" data-section="title">The Dark Side of the Moon</h1>
      <p data-name="blurb" class="rf-playlist__blurb" data-section="description">A landmark progressive rock album exploring themes of time, death, and madness.</p>
    </header>
    <ol data-name="tracks" class="rf-playlist__tracks" data-sequence="numbered">
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Speak to Me</span>
        <span data-name="track-artist" property="byArtist">Pink Floyd</span>
        <span data-name="track-duration">1:13</span>
        <meta property="duration" content="PT73S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Breathe</span>
        <span data-name="track-artist" property="byArtist">Pink Floyd</span>
        <span data-name="track-duration">2:43</span>
        <meta property="duration" content="PT163S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">On the Run</span>
        <span data-name="track-artist" property="byArtist">Pink Floyd</span>
        <span data-name="track-duration">3:36</span>
        <meta property="duration" content="PT216S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Time</span>
        <span data-name="track-artist" property="byArtist">Pink Floyd</span>
        <span data-name="track-duration">7:05</span>
        <meta property="duration" content="PT425S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">The Great Gig in the Sky</span>
        <span data-name="track-artist" property="byArtist">Pink Floyd</span>
        <span data-name="track-duration">4:44</span>
        <meta property="duration" content="PT284S" />
      </li>
    </ol>
  </div>
  <meta content="Pink Floyd" property="byArtist" />
</section>

Podcast

Use type="podcast" for episodic content with dates.

{% playlist type="podcast" %}
# Design Systems Weekly

A podcast about building and scaling design systems.

- **Component Libraries at Scale** (45:30) — March 2025
- **Token Architecture** (38:15) — February 2025
- **Accessibility First** (42:00) — January 2025
{% /playlist %}
<section data-field="content-section" data-rune="playlist" typeof="MusicPlaylist" data-rune-fields="{&quot;type&quot;:&quot;podcast&quot;,&quot;media-position&quot;:&quot;top&quot;}">
  <h1 id="design-systems-weekly" data-name="headline" property="name">Design Systems Weekly</h1>
  <p data-name="blurb">A podcast about building and scaling design systems.</p>
  <ol data-name="tracks">
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Component Libraries at Scale</span>
      <span data-name="track-duration">45:30</span>
      <meta property="duration" content="PT2730S">
      <span data-name="track-meta" property="datePublished">March 2025</span>
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Token Architecture</span>
      <span data-name="track-duration">38:15</span>
      <meta property="duration" content="PT2295S">
      <span data-name="track-meta" property="datePublished">February 2025</span>
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Accessibility First</span>
      <span data-name="track-duration">42:00</span>
      <meta property="duration" content="PT2520S">
      <span data-name="track-meta" property="datePublished">January 2025</span>
    </li>
  </ol>
</section>
podcast

Design Systems Weekly

A podcast about building and scaling design systems.

  1. Component Libraries at Scale45:30March 2025
  2. Token Architecture38:15February 2025
  3. Accessibility First42:00January 2025
<section data-field="content-section" typeof="MusicPlaylist" class="rf-playlist rf-playlist--podcast" data-type="podcast" data-media-position="top" data-rune="playlist" data-density="full">
  <div data-name="content" class="rf-playlist__content">
    <div data-name="eyebrow" data-zone="eyebrow" data-zone-layout="bar" class="rf-playlist__eyebrow">
      <span class="rf-badge" data-meta-type="category">podcast</span>
    </div>
    <header data-name="preamble" class="rf-playlist__preamble" data-section="preamble">
      <h1 id="design-systems-weekly" data-name="headline" property="name" class="rf-playlist__headline" data-section="title">Design Systems Weekly</h1>
      <p data-name="blurb" class="rf-playlist__blurb" data-section="description">A podcast about building and scaling design systems.</p>
    </header>
    <ol data-name="tracks" class="rf-playlist__tracks" data-sequence="numbered">
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Component Libraries at Scale</span>
        <span data-name="track-duration">45:30</span>
        <meta property="duration" content="PT2730S" />
        <span data-name="track-meta" property="datePublished">March 2025</span>
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Token Architecture</span>
        <span data-name="track-duration">38:15</span>
        <meta property="duration" content="PT2295S" />
        <span data-name="track-meta" property="datePublished">February 2025</span>
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Accessibility First</span>
        <span data-name="track-duration">42:00</span>
        <meta property="duration" content="PT2520S" />
        <span data-name="track-meta" property="datePublished">January 2025</span>
      </li>
    </ol>
  </div>
</section>

Per-track artists

When tracks have different artists, use italic text for per-track attribution. Omit the artist attribute to avoid a default.

{% playlist type="mix" %}
# Summer Vibes 2025

- **Midnight City** (4:03) *M83*
- **Electric Feel** (3:49) *MGMT*
- **Do I Wanna Know?** (4:32) *Arctic Monkeys*
- **Intro** (4:18) *The xx*
{% /playlist %}
<section data-field="content-section" data-rune="playlist" typeof="MusicPlaylist" data-rune-fields="{&quot;type&quot;:&quot;mix&quot;,&quot;media-position&quot;:&quot;top&quot;}">
  <h1 id="summer-vibes-2025" data-name="headline" property="name">Summer Vibes 2025</h1>
  <ol data-name="tracks">
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Midnight City</span>
      <span data-name="track-artist" property="byArtist">M83</span>
      <span data-name="track-duration">4:03</span>
      <meta property="duration" content="PT243S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Electric Feel</span>
      <span data-name="track-artist" property="byArtist">MGMT</span>
      <span data-name="track-duration">3:49</span>
      <meta property="duration" content="PT229S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Do I Wanna Know?</span>
      <span data-name="track-artist" property="byArtist">Arctic Monkeys</span>
      <span data-name="track-duration">4:32</span>
      <meta property="duration" content="PT272S">
    </li>
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Intro</span>
      <span data-name="track-artist" property="byArtist">The xx</span>
      <span data-name="track-duration">4:18</span>
      <meta property="duration" content="PT258S">
    </li>
  </ol>
</section>
mix

Summer Vibes 2025

  1. Midnight CityM834:03
  2. Electric FeelMGMT3:49
  3. Do I Wanna Know?Arctic Monkeys4:32
  4. IntroThe xx4:18
<section data-field="content-section" typeof="MusicPlaylist" class="rf-playlist rf-playlist--mix" data-type="mix" data-media-position="top" data-rune="playlist" data-density="full">
  <div data-name="content" class="rf-playlist__content">
    <div data-name="eyebrow" data-zone="eyebrow" data-zone-layout="bar" class="rf-playlist__eyebrow">
      <span class="rf-badge" data-meta-type="category">mix</span>
    </div>
    <header data-name="preamble" class="rf-playlist__preamble" data-section="preamble">
      <h1 id="summer-vibes-2025" data-name="headline" property="name" class="rf-playlist__headline" data-section="title">Summer Vibes 2025</h1>
    </header>
    <ol data-name="tracks" class="rf-playlist__tracks" data-sequence="numbered">
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Midnight City</span>
        <span data-name="track-artist" property="byArtist">M83</span>
        <span data-name="track-duration">4:03</span>
        <meta property="duration" content="PT243S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Electric Feel</span>
        <span data-name="track-artist" property="byArtist">MGMT</span>
        <span data-name="track-duration">3:49</span>
        <meta property="duration" content="PT229S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Do I Wanna Know?</span>
        <span data-name="track-artist" property="byArtist">Arctic Monkeys</span>
        <span data-name="track-duration">4:32</span>
        <meta property="duration" content="PT272S" />
      </li>
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Intro</span>
        <span data-name="track-artist" property="byArtist">The xx</span>
        <span data-name="track-duration">4:18</span>
        <meta property="duration" content="PT258S" />
      </li>
    </ol>
  </div>
</section>

With chapter markers

Tracks can include nested lists for chapter markers or lyrics. Use content="chapters" or content="lyrics" to force the display mode, or leave it as auto for automatic detection.

{% playlist type="podcast" content="chapters" %}
# Tech Talk: Web Components

- **Episode 42: Shadow DOM Deep Dive** (1:02:15)
  1. **Introduction** (0:00) Overview of today's topic
  2. **What is Shadow DOM?** (3:45) Core concepts explained
  3. **Styling strategies** (18:30) CSS custom properties and parts
  4. **Q&A** (45:00) Listener questions
{% /playlist %}
<section data-field="content-section" data-rune="playlist" typeof="MusicPlaylist" data-rune-fields="{&quot;type&quot;:&quot;podcast&quot;,&quot;media-position&quot;:&quot;top&quot;}">
  <h1 id="tech-talk:-web-components" data-name="headline" property="name">Tech Talk: Web Components</h1>
  <ol data-name="tracks">
    <li typeof="MusicRecording" data-field="track" property="track">
      <span data-name="track-name" property="name">Episode 42: Shadow DOM Deep Dive</span>
      <span data-name="track-duration">1:02:15</span>
      <meta property="duration" content="PT3735S">
      <ol data-name="chapters">
        <li data-time="0">
          <span data-name="chapter-name">Introduction</span>
          <span data-name="chapter-time">0:00</span>
        </li>
        <li data-time="225">
          <span data-name="chapter-name">What is Shadow DOM?</span>
          <span data-name="chapter-time">3:45</span>
        </li>
        <li data-time="1110">
          <span data-name="chapter-name">Styling strategies</span>
          <span data-name="chapter-time">18:30</span>
        </li>
        <li data-time="2700">
          <span data-name="chapter-name">Q&amp;A</span>
          <span data-name="chapter-time">45:00</span>
        </li>
      </ol>
    </li>
  </ol>
</section>
podcast

Tech Talk: Web Components

  1. Episode 42: Shadow DOM Deep Dive1:02:15
    1. Introduction0:00
    2. What is Shadow DOM?3:45
    3. Styling strategies18:30
    4. Q&A45:00
<section data-field="content-section" typeof="MusicPlaylist" class="rf-playlist rf-playlist--podcast" data-type="podcast" data-media-position="top" data-rune="playlist" data-density="full">
  <div data-name="content" class="rf-playlist__content">
    <div data-name="eyebrow" data-zone="eyebrow" data-zone-layout="bar" class="rf-playlist__eyebrow">
      <span class="rf-badge" data-meta-type="category">podcast</span>
    </div>
    <header data-name="preamble" class="rf-playlist__preamble" data-section="preamble">
      <h1 id="tech-talk:-web-components" data-name="headline" property="name" class="rf-playlist__headline" data-section="title">Tech Talk: Web Components</h1>
    </header>
    <ol data-name="tracks" class="rf-playlist__tracks" data-sequence="numbered">
      <li typeof="MusicRecording" data-field="track" property="track">
        <span data-name="track-name" property="name">Episode 42: Shadow DOM Deep Dive</span>
        <span data-name="track-duration">1:02:15</span>
        <meta property="duration" content="PT3735S" />
        <ol data-name="chapters">
          <li data-time="0">
            <span data-name="chapter-name">Introduction</span>
            <span data-name="chapter-time">0:00</span>
          </li>
          <li data-time="225">
            <span data-name="chapter-name">What is Shadow DOM?</span>
            <span data-name="chapter-time">3:45</span>
          </li>
          <li data-time="1110">
            <span data-name="chapter-name">Styling strategies</span>
            <span data-name="chapter-time">18:30</span>
          </li>
          <li data-time="2700">
            <span data-name="chapter-name">Q&amp;A</span>
            <span data-name="chapter-time">45:00</span>
          </li>
        </ol>
      </li>
    </ol>
  </div>
</section>

Attributes

AttributeTypeDefaultDescription
typestringalbumPlaylist type: album, podcast, audiobook, series, or mix
artiststringDefault artist applied to all tracks
playerbooleanShow an embedded audio player
contentstringautoCue point display: auto, lyrics, or chapters
idstringIdentifier for connecting an audio player rune

Section header

Playlist supports an optional eyebrow, headline, and blurb above the playlist content. Place a short paragraph or heading before the main content to use them. See Page sections for the full syntax.

Layout attributes

The body splits on --- into media (cover art) → content (tracks) zones (media-first in source). media-position controls visual placement independently of source order.

AttributeTypeDefaultDescription
media-positionstringtopWhere the cover sits: top, bottom, start (left), end (right)
media-ratiostringCover's share of the row when beside content (start/end): 1/3, 2/5, 1/2, 3/5, 2/3
valignstringCross-axis alignment when cover is beside content: top, center, bottom, stretch
collapsestringBreakpoint at which beside layouts collapse to a stack: sm, md, lg, never

Common attributes

All block runes share these attributes for layout and theming.

AttributeTypeDefaultDescription
widthstringcontentPage grid width: content, wide, or full
spacingstringVertical spacing: flush, tight, default, loose, or breathe
insetstringHorizontal padding: flush, tight, default, loose, or breathe
tintstringNamed colour tint from theme configuration
tint-modestringautoColour scheme override: auto, dark, or light
bgstringNamed background preset from theme configuration