Add Responsive YouTube Videos to Astro.JS MDX
Embed responsive YouTube videos in Astro MDX using astro-embed. Faster loading, better performance scores, and privacy-friendly.
Standard YouTube iframes kill your page performance. They load 1-2 MB of JavaScript before the user even clicks play. Your Lighthouse score drops, and your visitors wait for scripts they may never use.
astro-embed fixes this. It uses lite-youtube-embed under the hood — a custom element that shows a thumbnail and only loads the full YouTube player on click. The result is approximately 224x faster than a standard embed.
This guide covers two ways to add YouTube videos to your Astro MDX files: manual imports and automatic URL conversion.
Option 1: Manual import (recommended)
Install astro-embed
npm i astro-embed
If you only need YouTube and want a smaller install, you can use the standalone package instead:
npm i @astro-community/astro-embed-youtube
Import in your MDX file
Add the import statement in the frontmatter section of your .mdx file:
---
title: "My Blog Post"
description: "A post with a video"
---
import { YouTube } from "astro-embed";
Your content here.
<YouTube id="https://youtu.be/NkShQ1wwiCg" />
If you installed the standalone package, import from there instead:
import { YouTube } from "@astro-community/astro-embed-youtube";
YouTube component props
The <YouTube> component accepts these props:
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Video ID or full YouTube URL |
poster | string | auto | Custom poster image URL |
posterQuality | 'low' | 'default' | 'high' | 'max' | 'default' | Thumbnail resolution (120px to 1280px) |
params | string | — | YouTube player parameters (e.g., start=30&end=60) |
playlabel | string | 'Play' | Accessible label for the play button |
title | string | — | Overlay title text |
Examples:
<!-- Basic embed -->
<YouTube id="NkShQ1wwiCg" />
<!-- Full URL also works -->
<YouTube id="https://www.youtube.com/watch?v=NkShQ1wwiCg" />
<!-- Start at 30 seconds, end at 90 -->
<YouTube id="NkShQ1wwiCg" params="start=30&end=90" />
<!-- Custom poster image -->
<YouTube id="NkShQ1wwiCg" poster="https://example.com/custom-thumb.jpg" />
<!-- With overlay title -->
<YouTube id="NkShQ1wwiCg" title="Watch the full tutorial" />
Option 2: Auto-embed URLs in MDX
If you don’t want to manually add <YouTube> components, you can install the auto-embed integration. It automatically converts plain YouTube URLs in your MDX content into embed components.
Install
npm i @astro-community/astro-embed-integration
Configure
Add the integration to your astro.config.mjs:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import embeds from '@astro-community/astro-embed-integration';
export default defineConfig({
integrations: [mdx(), embeds()],
});
Usage
Just paste a YouTube URL on its own line in your MDX file. No import needed:
---
title: "My Post"
---
Check out this video:
https://youtu.be/NkShQ1wwiCg
The integration converts it to a `<YouTube>` component automatically.
This also works for Vimeo, Twitter/X posts, and Mastodon posts.
Supported services
astro-embed supports more than YouTube. You can embed from:
- YouTube —
<YouTube> - Vimeo —
<Vimeo> - Twitter/X —
<Tweet> - Mastodon —
<MastodonPost> - GitHub Gist
- Baseline status
- Open Graph —
<LinkPreview>
Import them all at once:
import { YouTube, Vimeo, Tweet, MastodonPost, LinkPreview } from "astro-embed";
Why this is faster than standard embeds
A normal YouTube <iframe> loads about 1.3-2.6 MB of JavaScript on page load — even if the visitor never plays the video. This tanks your Core Web Vitals.
The astro-embed approach:
- Shows a lightweight thumbnail (poster image)
- Loads zero YouTube JavaScript initially
- Loads the full iframe only when the user clicks play
- Uses
youtube-nocookie.comfor better privacy
The result: your page loads fast, your Lighthouse score stays high, and visitors only download YouTube’s scripts if they actually want to watch.
In Astro component files
You can also use astro-embed in .astro files, not just MDX:
---
import { YouTube } from "astro-embed";
---
<section>
<h2>Featured Video</h2>
<YouTube id="NkShQ1wwiCg" title="Featured tutorial" />
</section>
Troubleshooting
Component not rendering? Make sure you have the @astrojs/mdx integration installed. Run npx astro add mdx if you haven’t set it up yet.
Import not found? Check that you installed astro-embed (or the standalone package) and that the import path matches your install.
Auto-embed not working? Verify that @astro-community/astro-embed-integration is listed in your integrations array in astro.config.mjs, and that it comes after mdx().