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.

Add Responsive YouTube Videos to Astro.JS MDX

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.

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:

PropTypeDefaultDescription
idstringrequiredVideo ID or full YouTube URL
posterstringautoCustom poster image URL
posterQuality'low' | 'default' | 'high' | 'max''default'Thumbnail resolution (120px to 1280px)
paramsstringYouTube player parameters (e.g., start=30&end=60)
playlabelstring'Play'Accessible label for the play button
titlestringOverlay 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:

  1. Shows a lightweight thumbnail (poster image)
  2. Loads zero YouTube JavaScript initially
  3. Loads the full iframe only when the user clicks play
  4. Uses youtube-nocookie.com for 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.

YouTube Speed score with astro-embed

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().

DigitalOcean $100 Free Vultr $100 Free Hetzner €20 Free Hostinger VPS