Wavecast Radio

The sticky footer player (<podcast-footer>) must be present in your site’s base template for cross-page persistence.

Add this element just before the closing </body> tag in layouts/_default/baseof.html:

<p/oddhpdaaxoctt-daaapcs--ratttes-uustfrre-obbrfooovotl-eoeip>trneekrrism>d-a=pn"eeprnomtdacnaesntt-footer"

Framework Attributes

The data-turbolinks-permanent, data-turbo-permanent, and hx-preserve attributes ensure the footer survives page navigation when using these frameworks:

FrameworkAttributeWhat it does
Turbolinksdata-turbolinks-permanentPrevents Turbolinks from replacing the footer on navigation
Turbodata-turbo-permanentPrevents Turbo Drive from morphing/replacing the footer
htmxhx-preserveTells htmx to preserve the element during DOM swaps

If you don’t use any of these frameworks, omit those attributes: the footer will still persist via sessionStorage for vanilla page loads.

How Persistence Works

The player survives page navigations using multiple strategies:

  1. Framework hooks: data-turbolinks-permanent / data-turbo-permanent / hx-preserve keep the footer DOM element alive during SPA navigations
  2. sessionStorage fallback: State saved to sessionStorage on beforeunload, restored on next page load
  3. Vanilla HTML: Traditional page loads restore position, volume, mute, and speed from sessionStorage

State Saved

FieldDescription
currentTimePlayback position in seconds
pausedWhether audio was paused
volumeVolume level (0–1)
mutedMute state
playbackRatePlayback speed multiplier

Position Restore Rules

  • Exact URL match: Position only restored when the saved src matches the current element’s src
  • Staleness guard: Positions older than 1 hour are discarded
  • Paused-state estimation: If audio was paused, position is restored as-is
  • Playing-state estimation: If audio was playing, elapsed time since save is added
  • Deferred to loadedmetadata: Position set only after browser reports audio duration

Theme Toggle Integration

If your site has a dark/light theme toggle, make sure the footer’s CSS custom properties respond to your theme switching. The <podcast-footer> element responds to these selectors automatically:

[.h}dttahmBteluam[i-edPlt-althdta-eaayimr-enektr=hs"peaedompladeperc=lcka"it"sdeo]tasr-rspfkdoo"atdo]rhctkeaepsrotpt,dhl-ceafamyoseeotrt-vefarrore,oistapeborlned{ssto

If your theme uses different attribute names (e.g., body.dark or [color-scheme="dark"]), add your own rules:

b}b}ooddy--y--.pp.ppdoodooaddaddrccrcckaakaasssspttptto--o--dppdppcllcllaaaaaasyysyyteetee-rr-rrf--p--obtlbtogeaget:xy:xetetr#:r#:11{e#{e#1e1ee0e02e2ee0e0;e;e00;;
<<!h/Dt<<hOmh/b/tCle<<<ho{<<bmTamt!ed{!p/olYldei-ay-oddhpd>Pa>tt-d>b-daaxoyEnal>lctt-d>gehoFaaapch=c>ecos--rat"h{akotttesm{a{dt-uustl{r"efrre->sbcmrobbrf.eloaooovoStoniptl-eoi=ctnleip>tt"ke"arneeeunykrr.t"t.eism>Lft.rd-aa-i.}=pnn8t.}"eeg"l{prnu>e{omta"dagecne.naeCdsno}ttd}}-e{}f{o}o}.t"Se>irt"e.Title}}{{end}}</title>

Next Steps