Skip to content

Embed on Any Site ​

show.fm's embeds are web components: HTML elements that work on any site and in any framework. This page has copy-ready recipes for plain HTML, Astro, Next.js and Laravel.

If you would rather not write code, Embeds in the dashboard writes it for you, with a live preview. On WordPress, use the show.fm plugin instead.

The four elements ​

ElementWhat it showsKey attributes
<showfm-player>One episode, or the show's latest, with the full player.episode or podcast, size, transcript, mini-player
<showfm-episodes>A show's episodes as a list or grid. Each one plays in place.podcast, variant, layout, count, season, hide
<showfm-play>A play button for one episode. The first press opens a mini-player along the bottom of the page.episode or podcast, variant, size, mini-player
<showfm-transcript>A follow-along transcript that highlights each word as it is spoken.for (a player's or list's id), or episode, and height

Every element also takes theme, accent, load, lang and (except the transcript) credit. The embedded player reference lists the player's attributes. The package's README has every attribute of every element.

episode takes an episode ID and podcast takes a show's ID or slug. Prefer IDs: they never change, even if you rename the show. See Find your podcast and episode IDs.

Rules every recipe follows ​

  • Load the script once per page, however many elements you add.

  • Put a link inside each element. It shows before the script loads and without JavaScript, and search engines follow it.

  • Reserve the height, so the page doesn't jump when the element loads:

    ElementReserve
    Standard playermin-height: 291px (252px if your show hides "Powered by show.fm")
    Compact player (size="compact")min-height: 101px (83px without the credit)
    Episode list--showfm-height set to the list's height, as min-height
    Transcript--showfm-height: 377px (the default height), as min-height
  • Style with CSS custom properties, such as --showfm-accent and --showfm-font. The elements use your page's font unless you set one.

Plain HTML ​

html
<script async src="https://embed.cdn.media/player/v1.js"></script>

<showfm-player
	episode="11111111-2222-4333-8444-555555555555"
	style="display:block;min-height:291px"
>
	<a href="https://your-show.show.fm/e/your-episode">Listen to Your Episode on show.fm</a>
</showfm-player>

<showfm-episodes
	podcast="99999999-8888-4777-8666-555555555555"
	layout="list"
	count="5"
	style="display:block;--showfm-height:640px;min-height:var(--showfm-height)"
>
	<a href="https://your-show.show.fm">All episodes of Your Show on show.fm</a>
</showfm-episodes>

Astro ​

Install the package:

sh
npm install @showfm/embed

Make a component. Astro bundles the <script> and loads it once per page, however many times you use the component:

astro
---
// src/components/ShowfmPlayer.astro
const { episode, listenUrl, title } = Astro.props;
---

<showfm-player episode={episode} style="display:block;min-height:291px">
	<a href={listenUrl}>Listen to {title} on show.fm</a>
</showfm-player>

<script>
	import '@showfm/embed';
</script>

Use it on any page:

astro
<ShowfmPlayer
	episode="11111111-2222-4333-8444-555555555555"
	listenUrl="https://your-show.show.fm/e/your-episode"
	title="Your Episode"
/>

Next.js ​

Install the package:

sh
npm install @showfm/embed

The elements register in the browser, so import the package from a client component. The import is safe during server rendering too: it only registers the elements where the browser supports them.

tsx
// app/components/showfm-player.tsx
'use client';

import '@showfm/embed';

export function ShowfmPlayer({
	episode,
	listenUrl,
	title
}: {
	episode: string;
	listenUrl: string;
	title: string;
}) {
	return (
		<showfm-player episode={episode} style={{ display: 'block', minHeight: 291 }}>
			<a href={listenUrl}>Listen to {title} on show.fm</a>
		</showfm-player>
	);
}

For TypeScript, load the element types once, for example in a .d.ts file. Attribute values then type-check:

ts
import type {} from '@showfm/embed/jsx-react';

You can use a server component for the page around it. Only the file that imports @showfm/embed needs 'use client'.

Laravel ​

In a Blade view, use the elements as HTML. Blade's escapes your values:

blade
<showfm-player
    episode="{{ $episode->showfm_id }}"
    style="display:block;min-height:291px"
>
    <a href="{{ $episode->listen_url }}">Listen to {{ $episode->title }} on show.fm</a>
</showfm-player>

@once
    @push('scripts')
        <script async src="https://embed.cdn.media/player/v1.js"></script>
    @endpush
@endonce

Your layout needs @stack('scripts') for @push to land. If you build assets with Vite, you can instead run npm install @showfm/embed and add import '@showfm/embed'; to resources/js/app.js.

Load on click ​

Some sites must ask for consent before loading anything from another service. With load="click", an element shows a placeholder in your accent and requests nothing from show.fm until a visitor presses it.

  1. Add load="click" to each element.
  2. Leave out the v1.js script tag.
  3. After the elements, paste the click loader inline, once per page:
html
<showfm-player
	episode="11111111-2222-4333-8444-555555555555"
	load="click"
	style="display:block;min-height:291px"
>
	<a href="https://your-show.show.fm/e/your-episode">Listen to Your Episode on show.fm</a>
</showfm-player>

<script>
	/* the contents of @showfm/embed/cdn/click-loader.js */
</script>

The loader must be inline, not a src: loading it from another site would itself be a request. Get its contents from the npm package (@showfm/embed/cdn/click-loader.js), or turn on Load on click in Embeds and copy the code.

The first press loads the player script from embed.cdn.media. To serve the script from your own site instead, copy the package's cdn/ folder (v1.js with its chunks/ and locales/ folders) to your site and use click-loader-local.js. It has no address of its own, so it only ever loads the v1.js you point it to:

html
<script>
	window.showfmEmbedSrc = '/assets/showfm-embed/v1.js';
</script>
<script>
	/* the contents of @showfm/embed/cdn/click-loader-local.js */
</script>

If your consent tool can run code when a visitor agrees, call showfm.load() to load every element at once.

The "Powered by show.fm" credit ​

Embeds show a small "Powered by show.fm" credit, once per page. Whether it shows is a setting of the show, not of your page:

  • Show owners on Creator plans and up can turn on Hide "Powered by show.fm" in Settings → Distribution. Every embed of that show then hides it, including code already on other sites. See Remove "Powered by show.fm".
  • credit="on" always shows the credit on that embed.
  • credit="off" hides it only where the show's setting already does, so it works like the default (auto). Outside the show.fm WordPress plugin, an embed can't hide the credit on its own.

When your show hides the credit, reserve the smaller player heights above.

Was this page helpful?