Which WordPress Radio and Audio Players Keep Playing Across Pages? A Tested List

Uncategorized 6 min read

EDITOR NOTE — remove before publishing. Status column is honest as of 2.4.2 — update after the compatibility verification pass. Consider adding assets/animations/player-setup-walkthrough.svg under “How to set any of these up”.

Before you install anything, you want one question answered: will this work with the player I already have?

Fair question, and it’s the one we’re asked most. So here’s the honest list — what we’ve seen working in production, what has caveats, and what we haven’t tested. We’ve marked that last category clearly rather than quietly implying everything works.

First, the one rule that decides everything

Your player has to render on every page. Not “on the pages where you want music” — every page. If the player sits inside the content of a single page, it cannot persist, because the content area is exactly what gets swapped during navigation. It will vanish the moment someone clicks a link, whatever you configure.

In practice that means one of:

  • Your plugin’s sticky, floating or fixed bar mode — most radio plugins have one
  • A footer template that outputs site-wide
  • A theme widget area that appears on every page

If your plugin only renders inside post content and offers no sticky mode, it can’t work. Better to know that in thirty seconds than after an hour.

How to read the list

  • Confirmed — a user has this running in production.
  • Works, with caveats — running, but with a known issue. Read the notes.
  • Unverified — the selector comes from reading the plugin’s markup, but we haven’t run it on a live install. It should work. We haven’t proved it.

We’d rather publish “unverified” than have you trust a selector nobody has tested.

Custom HTML5 player with a stream URL

Confirmed. The most common setup we see, including the growing number of players people generate with ChatGPT and drop into Code Snippets, WPCode, or a theme footer widget.

Because you own the markup, this route is free — no Pro licence needed:

<div id="radio-bar"
     data-ajaxpress-persist
     data-persist-key="live-radio">
  <audio id="radio-audio" src="https://stream.example.com/live" preload="none"></audio>
  <button id="radio-play">Play</button>
</div>

Mark the wrapper, not the <audio> tag — the button has to travel with it. And if you’re using Code Snippets or WPCode, set the snippet to run in the site footer on every page, not just the front page.

Mediastream

Works, with caveats. Three separate users have reported Mediastream setups, usually alongside Elementor and the Hello Elementor theme.

#mediastream-player

Confirm the real id by inspecting your own player first — some installs render a different one.

Caveat one: on some setups the player only appears after a second click. Adding data-persist-key to the wrapper has resolved this in some cases.

Caveat two: doubled audio has been reported — see below. It’s fixable, and it isn’t really a Mediastream problem.

MP3 Audio Player by Sonaar

Works, with caveats — specifically with the sticky player.

.sonaar-sticky-player, #sonaar-sticky-player

Both are listed because the markup varies by version — inspect your site and keep whichever matches.

Important: the non-sticky Sonaar player sits inside post content and will be replaced on navigation by design. Turn the sticky player on in Sonaar’s own settings first. No AjaxPress setting can rescue a player that lives in the content area.

Good news: the sticky player is already position: fixed, so it usually sidesteps the positioning issue below.

Elementor Audio / Video widget

Unverified — common in reports, but we don’t have a confirmed production setup.

Elementor doesn’t give widgets a friendly id, so assign one. Select the widget, open Advanced → CSS ID, set something like my-radio-player, then use #my-radio-player.

Put the widget in a footer template (Elementor → Templates → Theme Builder), not on individual pages.

Watch for: Elementor widgets are usually styled through their parent section. Once lifted, those styles stop applying.

Radio Player, Radio Station, StreamCast, Hero

All unverified. Starting points:

PluginTryNote
Radio Player (MP3/OGG/AAC).radio-player-containerEnable sticky/fixed mode
Radio StationSet a CSS ID on the player widgetPersist only the player — schedule and “now playing” widgets should update per page
StreamCast.streamcast-playerUse the floating layout if available
Hero by LambertGroupYour configured container idHeavily JS-driven; check the console if it misbehaves

WaveSurfer players

Unverified. Try #waveform or .wavesurfer-container.

Watch for: WaveSurfer draws into a <canvas> sized to its container, so moving it can leave the waveform at the wrong width. If it renders squashed:

document.addEventListener('ajaxpress:ready', () => {
  if (window.wavesurfer) window.wavesurfer.drawBuffer();
});

How to set any of these up

You can edit the markup (free): add data-ajaxpress-persist to the wrapper. Three other markers work identically — the class ajaxpress-persist, an id starting with persistent-, or data-persist on an <audio> tag.

A plugin renders it (Pro): go to Settings → AjaxPress → Advanced → Media Players and paste the selector. Multiple players, comma-separated, are fine.

Before saving, check the selector matches exactly one element. In the browser console:

document.querySelectorAll('#your-selector').length

You want 1. Zero means the selector is wrong; more than one means it’s too broad.

If you hear two streams at once

AjaxPress has to recognise your player as the same player on each new page. It checks, in order: a data-persist-key attribute, the element’s id, the src of the audio or iframe inside it, and finally a fingerprint of the HTML.

If your stream URL carries a cache-busting parameter like ?t=1736301234, that URL differs on every page. AjaxPress sees a brand-new player, keeps the old one and adds the new one — two streams over each other.

One attribute fixes it:

<div id="radio-bar" data-persist-key="live-radio">

If your player jumps to the wrong place

To survive navigation, your player is physically moved out of the page into a fixed-position container at the end of <body>.

So it leaves your footer. CSS written as .site-footer .radio-player { … } stops applying, and a player that relied on its old parent for placement ends up somewhere unexpected — usually the bottom of the document.

Give it positioning of its own:

#radio-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
}

Your player isn’t listed

The method works for anything. Right-click the player, choose Inspect, walk up the HTML until you find the outermost element containing every part of the player, and use its id or class.

If you get a player working that isn’t here, email [email protected] with the plugin name and selector. We’ll add it and credit you — the fastest way to help the next person with your setup.

Related Posts