Markdown Embed Video
When writing technical docs or building a project showcase, you often need to embed a video demo — a feature walkthrough, a tutorial recording, or a meeting replay. Markdown doesn't have a native video syntax like it does for Markdown images with ![](). But since Markdown supports inline HTML, you can use <iframe> to embed videos. Let's cover all the embedding methods, platform compatibility, and what to do when iframes get stripped.
Why Markdown Has No Native Video Syntax
Here's the thing: neither standard Markdown nor the CommonMark spec defines a video embed syntax . Markdown was designed as "an easy-to-read, easy-to-write plain text format," and video embedding falls outside that scope. So whether you want to embed a YouTube video, a Vimeo clip, or a local video file, you'll need HTML.
Specifically, there are four approaches:
- HTML
<iframe>tag: embed videos from online platforms (YouTube, Vimeo, Bilibili) - Markdown image + link: use a video thumbnail as a "fake embed" that links to the video page
- HTML5
<video>tag: embed local video files - Platform-specific extensions: custom syntax supported by certain editors or plugins
Let's go through each one.
Embed YouTube Video with iframe
YouTube is the most common video embed need. The key is getting the embed URL — it's different from the regular watch URL. You need the youtube.com/embed/ path:
<iframe width="560" height="315"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>The dQw4w9WgXcQ part is the video ID — the string after watch?v= in a YouTube URL.
How to Find the Video ID
A YouTube video URL usually looks like https://www.youtube.com/watch?v=dQw4w9WgXcQ. The value after v= is the video ID. Append it to https://www.youtube.com/embed/ and you're set.
If the link is a short URL like https://youtu.be/dQw4w9WgXcQ, the last segment is also the video ID.
iframe Attributes Explained
Honestly, copying the code above and swapping the video ID is enough for most cases. But understanding the attributes helps:
| Attribute | Purpose |
|---|---|
width / height | Player dimensions in pixels |
src | Video embed address, must use the /embed/ format |
title | Accessibility title — screen readers use this to describe the iframe content |
frameborder="0" | Removes the iframe border (deprecated in HTML5, but still widely used) |
allow | Controls browser features the video can use (autoplay, clipboard, etc.) |
allowfullscreen | Lets users click the fullscreen button |
The allow attribute contains YouTube's recommended security permission list. Just copy it as-is. If you don't mind losing some features, keeping only allowfullscreen works fine too.
Embed Vimeo Video with iframe
Vimeo embedding works almost identically to YouTube, just with a different embed URL:
<iframe width="640" height="360"
src="https://player.vimeo.com/video/19706846"
frameborder="0"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen>
</iframe>Vimeo's video ID is the number at the end of the URL, like 19706846 in https://vimeo.com/19706846. Note that Vimeo's player domain is player.vimeo.com, not www.vimeo.com.
One thing to watch out for: if you put https://vimeo.com/19706846 directly in the iframe's src, you won't get a player — you must use the player.vimeo.com/video/ path.
Embed Bilibili Video with iframe
For users who work with Chinese video platforms, Bilibili (B站) is commonly used. Embedding Bilibili videos also uses an iframe:
<iframe width="640" height="360"
src="//player.bilibili.com/player.html?bvid=BV1xx411c7mD&page=1"
frameborder="0"
allowfullscreen>
</iframe>Bilibili's embed URL requires the BV ID (BV1xx411c7mD), which is the alphanumeric string in the video URL. The page=1 parameter specifies the first part (for multi-part videos, change it to the corresponding page number).
You can find the BV ID in the video URL — it's the string starting with BV in links like https://www.bilibili.com/video/BV1xx411c7mD.
Thumbnail Link Method: The Universal Fallback
The iframe approach has one big problem: many platforms strip iframe tags entirely. GitHub is the most notable example — its HTML allowlist doesn't include iframes . You write an iframe in a GitHub README, push it, and... nothing shows up.
The most reliable fallback is using Markdown's image + link syntax to create a "looks-like-a-video" thumbnail:
[](https://www.youtube.com/watch?v=dQw4w9WgXcQ)This displays the YouTube video thumbnail and links to the video page. It uses pure Markdown link + Markdown image syntax, so it works on every platform .
YouTube thumbnail URLs follow a predictable pattern — no need to take screenshots manually:
| Thumbnail | URL Format | Resolution |
|---|---|---|
| Default | https://img.youtube.com/vi/VIDEO_ID/default.jpg | 120×90 |
| Medium | https://img.youtube.com/vi/VIDEO_ID/mqdefault.jpg | 320×180 |
| High Quality | https://img.youtube.com/vi/VIDEO_ID/hqdefault.jpg | 480×360 |
| Max Res | https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg | 1280×720 |
hqdefault.jpg is usually the best balance between quality and load time.
Adding a Play Button
A thumbnail still doesn't quite look like a video player. A common trick is overlaying a play button icon on the thumbnail — but that requires CSS or SVG, which isn't possible in pure Markdown. YouTube's hqdefault.jpg already has that semi-transparent bar in the middle, which helps.
I once used this method in an open-source project's README for a feature demo video. Sure, clicking it takes you to YouTube instead of playing inline, but at least users see the video cover and know there's a video to watch. Way better than a plain text link that nobody would notice.
HTML5 video Tag: Embed Local Video Files
If you have a local .mp4 file to embed (like a demo recording in the same repo), you can use the HTML5 <video> tag:
<video width="640" height="360" controls>
<source src="demo.mp4" type="video/mp4">
Your browser does not support the video tag
</video>The controls attribute shows the playback controls (play/pause, progress bar, volume). The src can be a relative path or an absolute URL.
That said, this approach is quite limited. GitHub strips <video> tags, and many online Markdown editors don't support it either. It's best suited for static sites you control, like Jekyll or Hugo.
Responsive Video Embedding
Fixed-width iframes look terrible on mobile — they either overflow the screen or shrink to nothing. If you're using Markdown on your own site (Jekyll, Hugo, etc.), you can make videos responsive with CSS:
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
frameborder="0"
allowfullscreen>
</iframe>
</div>The padding-bottom: 56.25% represents a 16:9 aspect ratio (9÷16 = 0.5625). The iframe uses absolute positioning to fill the container, so the player always maintains a 16:9 ratio regardless of screen width.
For modern browsers, there's a cleaner approach:
<div style="aspect-ratio: 16/9; width: 100%;">
<iframe style="width: 100%; height: 100%;"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
allowfullscreen>
</iframe>
</div>The aspect-ratio property is a newer CSS feature supported by all major browsers. Much more concise. However, GitHub strips inline styles, so this only works on sites you control.
I learned this the hard way on a Jekyll blog — I used width="560" height="315" fixed dimensions, and on mobile the video stretched way past the screen edge. You had to scroll horizontally to watch it. Switching to the aspect-ratio approach fixed it for both mobile and desktop.
Platform-Specific Extension Syntax
A few platforms provide custom video embed syntax, but these only work in their specific environments:
markdown-it-video Plugin
@[youtube](dQw4w9WgXcQ)
@[vimeo](19706846)This syntax comes from the markdown-it-video plugin. Projects using markdown-it as their parser (like Node.js-based sites) can install this plugin for support .
October CMS
!October CMS's Markdown parser supports this special syntax, which gets converted to a standard iframe embed.
These custom syntaxes aren't portable — they break on any other platform. Unless you're certain you'll only use a specific environment, stick with standard iframes.
Platform Compatibility Comparison
Video embed support varies significantly across platforms:
| Platform | <iframe> | <video> | Thumbnail Link | Notes |
|---|---|---|---|---|
| Jekyll / Hugo | ✅ | ✅ | ✅ | Self-hosted sites, HTML fully preserved |
| Obsidian | ✅ | ✅ | ✅ | Local preview supports iframes |
| Typora | ✅ | ✅ | ✅ | Inline playback in the editor |
| VS Code Preview | ⚠️ | ❌ | ✅ | Partial iframe support, security restrictions apply |
| GitLab | ✅ | ❌ | ✅ | GLFM supports iframes |
| GitHub | ❌ | ❌ | ✅ | HTML allowlist excludes iframes |
| Notion | ❌ | ❌ | ❌ | Use /embed command instead |
| Stack Overflow | ❌ | ❌ | ⚠️ | Images work, but video embedding is limited |
Key takeaways:
- GitHub is the most restrictive platform — no iframe or video support, only the thumbnail link method works
- GitLab actually supports iframes, which gives it an edge over GitHub for docs with video
- Obsidian and Typora are the most video-friendly, both iframe and video tags work
- Notion has its own embedding method — just use the
/embedcommand and paste the video URL, no code needed
Practical Use Cases
Demo Video in a Project README
## Feature Demo
Click to watch the walkthrough:
[](https://www.youtube.com/watch?v=dQw4w9WgXcQ)The most common approach on GitHub. It's not a true inline player, but at least viewers see the video cover.
Tutorial Video in a Blog Post
<iframe width="560" height="315"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Tutorial Video"
allowfullscreen>
</iframe>In blog systems like Jekyll or Hugo, iframes work directly. Readers can watch without leaving the page.
Meeting Recording in Obsidian Notes
## 2024-03-15 Product Review Meeting
<iframe width="560" height="315"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
allowfullscreen>
</iframe>When taking meeting notes in Obsidian, embed the recording right in the note. No need to dig through chat history for the video link later.
FAQ
How do I embed a video in a GitHub README?
GitHub doesn't support <iframe> or <video> tags. The only option is the thumbnail link method:
[](https://www.youtube.com/watch?v=VIDEO_ID)This isn't a true video embed — it shows the video thumbnail and links to YouTube for playback .
Does Markdown have a video syntax?
No. Standard Markdown and the CommonMark spec don't include a video embed syntax . All video embedding requires HTML tags (iframe or video).
Why isn't my iframe showing up?
The two most common reasons:
- The platform strips iframes: GitHub and some online editors remove iframe tags for security. Check whether your target platform supports iframes.
- Wrong embed URL format: YouTube's iframe src must be
youtube.com/embed/VIDEO_ID, notyoutube.com/watch?v=VIDEO_ID. Vimeo's must beplayer.vimeo.com/video/ID. Using the wrong URL results in a blank or broken iframe.
How do I make an embedded video responsive?
Wrap the iframe with CSS aspect-ratio:
<div style="aspect-ratio: 16/9; width: 100%;">
<iframe style="width: 100%; height: 100%;"
src="https://www.youtube.com/embed/VIDEO_ID"
allowfullscreen>
</iframe>
</div>This requires the platform to support inline styles (GitHub doesn't).
How do I get the embed code for a Bilibili video?
On the Bilibili video page, click the "Share" button and select "Embed Code" to get the full iframe snippet. Or manually construct it: //player.bilibili.com/player.html?bvid=YOUR_BV_ID.
References
: Markdown Guide — Extended Syntax: MDN Web Docs — HTML iframe Element: GitHub Docs — Writing expressions in Markdown: GitHub — markdown-it-video plugin