Appearance
Are you an LLM? You can read better optimized documentation at /docs/developers/embed-on-any-site.md for this page in Markdown format
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
| Element | What it shows | Key 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:
Element Reserve Standard player min-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-heightset to the list's height, asmin-heightTranscript --showfm-height: 377px(the default height), asmin-heightStyle with CSS custom properties, such as
--showfm-accentand--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/embedMake 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/embedThe 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
@endonceYour 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.
- Add
load="click"to each element. - Leave out the
v1.jsscript tag. - 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.
Related
- Embedded Player: the player's attributes, iframes and oEmbed.
- Embeds: build the code in the dashboard.
- show.fm for WordPress