Rich Embeds
Rich Embeds
/plugin-embeds transforms bare URLs in your Markdown into rich oEmbed content at build time — YouTube videos, Twitter/X posts, GitHub Gists, CodePen pens, Spotify tracks, and Vimeo videos.
Because embedding happens at build time, no client-side JavaScript is needed. The rendered HTML is static.
Live example
Here's a YouTube embed produced by placing a bare URL on its own line:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
Installation
pnpm add /plugin-embeds
Setup
// stedefast.config.ts
import { defineConfig } from "@stedefast/core";
import { EmbedsPlugin } from "/plugin-embeds";
export default defineConfig({
// ...
plugins: [
EmbedsPlugin({
maxWidth: 720,
onError: "link",
}),
],
});
Usage
Place a URL on its own line in your Markdown (no surrounding text, no link syntax):
Check out this video:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
And this gist:
https://gist.github.com/octocat/1234567
The plugin detects these "bare URL paragraphs" and replaces them with the provider's oEmbed HTML.
Supported Providers
| Provider | URL pattern |
|---|---|
| YouTube | youtube.com/watch, youtu.be/ |
| Twitter/X | twitter.com/*/status/, x.com/*/status/ |
| GitHub Gist | gist.github.com/ |
| CodePen | codepen.io/ |
| Spotify | open.spotify.com/track/album/playlist/episode/ |
| Vimeo | vimeo.com/ |
Adding Custom Providers
EmbedsPlugin({
providers: [
{
name: "Figma",
pattern: /https?:\/\/www\.figma\.com\//,
endpoint: "https://www.figma.com/api/oembed",
maxWidth: 800,
},
],
})
Custom providers are merged with the built-in list. To replace the built-in list entirely, use overrideProviders.
Options
| Option | Type | Default | Description |
|---|---|---|---|
providers |
OEmbedProvider[] |
[] |
Additional providers merged with built-ins |
overrideProviders |
OEmbedProvider[] |
— | Replace all built-in providers |
maxWidth |
number |
800 |
Default max width for embeds |
wrapperClass |
string |
"sf-embed" |
CSS class on the wrapper <div> |
onError |
"link" | "skip" | "error" |
"link" |
What to do when oEmbed fetch fails |
onError behaviour
"link"— render a plain<a href>hyperlink (safe fallback)"skip"— leave the URL as a plain paragraph"error"— throw a build error (useful for CI)
Styling
Embeds are wrapped in <div class="sf-embed sf-embed--youtube"> (provider name slugified). Add responsive styles in your theme:
.sf-embed {
margin: 2rem 0;
}
.sf-embed iframe {
max-width: 100%;
aspect-ratio: 16 / 9;
height: auto;
}
Important Notes
- Build-time fetches — oEmbed requests are made at
stedefast buildtime. Provider rate limits and network availability apply. allowDangerousHtml— Stedefast's rehype pipeline must have this enabled (it is by default viarehype-raw) for the injected provider HTML to pass through to the output.- Twitter embeds — Twitter/X's oEmbed returns a
<blockquote>+ script. The script call is included in the static HTML; Twitter's JS loads on the client to render the card.