Embeds
Flexweg CMS ships with four embed providers out of the box: YouTube, Vimeo, Twitter/X, and Spotify. Each is its own block in the inserter; pasting a URL parses out the resource id and renders the provider's official iframe / blockquote at publish time.
The embeds are provided by the flexweg-embeds must-use plugin (always-on). Disabling them isn't possible (they're must-use); but if you don't need them, simply don't insert the blocks.
How to insert
Option 1 — the inserter
Type / then the provider name:
/youtube→ YouTube block/vimeo→ Vimeo block/twitter(or/x) → Twitter / X block/spotify→ Spotify block
The block inserts with an empty data-id attribute. Use the inspector (right sidebar, Block tab) to paste the URL.
Option 2 — paste a URL directly
Paste a YouTube / Vimeo / Twitter / Spotify URL into a paragraph. The editor recognises the URL pattern, auto-converts the paragraph into the matching embed block.
Recognised URL patterns:
| Provider | Patterns |
|---|---|
| YouTube | https://www.youtube.com/watch?v=…, https://youtu.be/…, https://www.youtube.com/embed/… |
| Vimeo | https://vimeo.com/<id> |
| Twitter / X | https://twitter.com/<user>/status/<id>, https://x.com/<user>/status/<id> |
| Spotify | https://open.spotify.com/track/<id>, /album/<id>, /episode/<id>, /playlist/<id> |
If the URL doesn't match any provider, the paragraph stays as plain text (the URL becomes a clickable link if you have the link mark).
Provider details
YouTube
- What's embedded: YouTube's standard iframe player at
https://www.youtube.com/embed/<id> - Attributes parsed: video id (
?v=…oryoutu.be/<id>orembed/<id>) - No additional script needed — iframe-only, no JS dependency
- Privacy mode: not currently — uses youtube.com (which sets cookies). If you want privacy-respecting (
youtube-nocookie.com), patch theflexweg-embedsprovider definition or write a follow-up plugin that filterspost.html.bodyto swap the domain.
Vimeo
- What's embedded: Vimeo's iframe player at
https://player.vimeo.com/video/<id> - Attributes parsed: video id (numeric)
- No additional script needed — iframe-only
Twitter / X
- What's embedded: Twitter's
<blockquote class="twitter-tweet">markup, which Twitter'swidgets.jsscript transforms into a styled tweet card client-side - Attributes parsed: tweet id, author handle
- Additional script:
https://platform.twitter.com/widgets.js— injected automatically into the page's</body>when at least one Twitter embed is on the page (per-page detection — pages without Twitter embeds don't load the script)
Spotify
- What's embedded: Spotify's iframe player at
https://open.spotify.com/embed/<type>/<id> - Attributes parsed: type (track / album / episode / playlist) + id
- No additional script needed — iframe-only
Per-page script injection
Some embeds (Twitter today, others potentially in the future) need a JavaScript runtime to render. The plugin tracks which providers are used per page and injects the right script(s) only on pages that need them.
For example:
- A page with only YouTube embeds → no extra script (YouTube is iframe-only)
- A page with a Twitter embed →
widgets.jsinjected before</body> - A page with both YouTube AND Twitter →
widgets.jsinjected - A page with no embeds → no scripts, no overhead
This keeps pages fast for the typical case where embeds are sparse.
Per-page CSS
The flexweg-embeds plugin also injects a small <style> block on every page that has at least one embed, with baseline CSS for embed sizing (responsive 16:9 wrappers for video, max-width for tweets, etc.). Themes can override this CSS — the embed blocks use semantic class names (flexweg-embed-youtube, etc.) that can be styled.
Markdown round-trip
Each embed is stored in the post's markdown as a marker:
<div data-cms-embed="youtube" data-id="dQw4w9WgXcQ" data-url="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></div>
The marker round-trips losslessly through the editor — saving and reopening produces identical content. At publish time, the publisher's post.html.body filter scans for these markers and replaces each with the provider's actual embed HTML.
The data-url attribute preserves the original URL for editing UX (the inspector pre-fills with this URL when you re-open a post).
Editing an existing embed
Click the embed block in the editor. The right sidebar's Block tab shows:
- The current URL (editable)
- Provider type (read-only — to switch providers, delete the block and re-insert)
Removing an embed
Click the embed → block toolbar (top-right of the block) → 🗑 delete. The marker is removed from the markdown. On next publish, the resulting HTML page omits the embed.
Limitations
- No custom embed providers in v1 — to add (e.g. Instagram, TikTok, CodePen), you'd add a new entry to the
flexweg-embedsplugin's provider list (or fork the plugin). Seesrc/mu-plugins/flexweg-embeds/providers.ts. - No oEmbed — providers are hardcoded URL → embed HTML, not via the oEmbed protocol. Adding an oEmbed-aware fallback for unknown URLs is a possible future enhancement.
- No live preview in the editor — the editor shows the embed as a placeholder (icon + URL), not the actual rendered video / tweet. Save and view the published post to see the real embed.
Continue
- flexweg-embeds plugin — full plugin reference
- Custom HTML — for embeds that aren't built-in providers
- Block authoring — to build your own embed provider