Embed de YouTube en Astro: Añade Videos Responsive en MDX (2026)
Aprende a añadir embeds de YouTube responsive en Astro MDX con astro-embed. La fachada de lite-youtube se carga al hacer clic para páginas más rápidas y mejores puntuaciones en Lighthouse.
47 min de lectura

Los iframes estándar de YouTube matan el rendimiento de la página. Descargan entre 1 y 2 MB de JavaScript al cargar, antes de que el visitante siquiera pulse reproducir. Las puntuaciones de Lighthouse caen y todo el mundo espera por código del reproductor que quizá nunca use.
Para un embed de YouTube rápido en tu MDX de Astro, usa astro-embed. Envuelve lite-youtube-embed por dentro: un elemento personalizado que muestra una miniatura y carga el reproductor completo solo al hacer clic. El README de lite-youtube afirma que es ~224x más rápido que un embed estándar.
Esta guía cubre ambos caminos: una importación manual del componente (mi opción por defecto) y la conversión automática de URLs. También cubre la trampa de compatibilidad de versiones de Astro, la privacidad del póster y un paso de verificación, para que puedas ponerlo en marcha esta misma noche.
Si quieres el panorama completo sobre el manejo de video en SSG y SSR, lee cómo añadir videos de YouTube a tu blog de Astro en SSG y SSR. ¿Aún no tienes sitio? Primero crea un blog de Astro gratis en 30 minutos y luego vuelve.
Por qué los embeds estándar de YouTube ralentizan tu sitio
Un <iframe> normal descarga aproximadamente entre 1.3 y 2.6 MB de JavaScript al cargar la página (aproximado, varía según lo que YouTube publique ese mes). Ese coste se paga aunque el visitante nunca reproduzca el video. En una página de contenido con dos o tres embeds, son varios MB de código de terceros compitiendo con tus fuentes e imágenes por ancho de banda y tiempo del hilo principal.
La solución es una fachada. Renderizas un marcador de posición ligero (una imagen de póster más unos pocos KB de CSS y JavaScript) y solo cargas el reproductor real de YouTube después de que el visitante haga clic. Eso es exactamente lo que hace lite-youtube-embed, y astro-embed lo envuelve como un componente de Astro. El iframe del reproductor viene de youtube-nocookie.com, así que la reproducción también es un poco más amigable con la privacidad.
Qué es una fachada
Una fachada es un marcador de posición ligero que difiere el reproductor de terceros hasta que el visitante interactúa con él. Mismo resultado visual, mucho menos trabajo al cargar la página.
Esto es lo que solicita cada enfoque:
Izquierda: el coste se paga de inmediato. Derecha: el coste solo se paga tras un clic deliberado.
Requisitos previos
Antes de la Opción 1 o la Opción 2, necesitas:
- Un proyecto de Astro que ya compile (usa el Node.js LTS que requiera tu versión de Astro; comprueba
node -vcontra la documentación de Astro para tu versión) - La integración de MDX instalada:
npx astro add mdxsi te falta - Acceso a
astro.config.mjs(la Opción 2 lo edita) - Tu versión de Astro anotada:
npx astro --version(la Opción 2 la necesita)
Aquí no hay coste de servidor. Es un cambio en tiempo de compilación más unos pocos KB de código de fachada del lado del cliente. El único «coste» real es la gestión de dependencias y versiones, y hay una trampa: la última integración de auto-embed requiere Astro 7.2.4 o superior. La tabla de compatibilidad de la Opción 2 tiene los detalles.
Opción 1: añade un video de YouTube a Astro MDX con una importación manual
Este es el camino recomendado. Es explícito, tolerante a versiones y funciona en Astro 5, 6 y 7. Si quieres un embed de YouTube responsive en Astro MDX y no te importa escribir una etiqueta de componente, usa este.
Instala astro-embed
Paquete completo (recomendado)
npm i astro-embedVersión actual: astro-embed@0.14.0 (publicada el 2026-08-27). Esto incluye todos los componentes de servicios (YouTube, Vimeo y el resto).
Solo YouTube (instalación más ligera)
npm i @astro-community/astro-embed-youtubeVersión actual: 0.5.10. El mismo componente <YouTube>, sin otros servicios. Elige esta si nunca vas a incrustar Vimeo o Bluesky y te importa mantener node_modules ligero.
Importa el componente de YouTube en tu archivo MDX
Añade la importación después del frontmatter de tu archivo .mdx:
---
title: "My Blog Post"
description: "A post with a video"
---
import { YouTube } from "astro-embed";
Your content here.
<YouTube id="https://youtu.be/NkShQ1wwiCg" />Si instalaste el paquete independiente, importa desde ahí:
import { YouTube } from "@astro-community/astro-embed-youtube";La prop id acepta un ID de video suelto, un enlace corto youtu.be o una URL completa watch?v=. Las tres funcionan.
Verifícalo antes de seguir: ejecuta npm run dev, abre el post y confirma que se renderiza una miniatura de póster clicable. Abre primero la pestaña Network de las devtools. Si ves una solicitud a youtube.com/embed antes de hacer clic en reproducir, algo va mal.
Props del componente YouTube
El componente <YouTube> acepta estas props:
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
id |
string | obligatoria | ID del video o URL completa de YouTube |
poster |
string | auto | URL de imagen de póster personalizada |
posterQuality |
'low' | 'default' | 'high' | 'max' |
'default' |
Resolución de la miniatura (120px a 1280px) |
params |
string | ninguno | Parámetros del reproductor de YouTube (p. ej., start=30&end=60) |
playlabel |
string | 'Play' |
Etiqueta accesible del botón de reproducción |
title |
string | ninguno | Texto del título superpuesto |
posterQuality corresponde a tamaños reales de miniatura: low es 120px, default es 480px, high es 640px, max es 1280px.
playlabel es el nombre de la prop en minúsculas (refleja el atributo de lite-youtube). Es a la vez la etiqueta accesible del botón de reproducción y el gancho para la localización.
Ejemplos:
<!-- 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" />
<!-- Tighter player: no controls, clip a segment, no related videos -->
<YouTube id="NkShQ1wwiCg" params="controls=0&start=10&end=30&rel=0" />posterQuality='max' no siempre está disponible
maxresdefault.jpg no existe para todos los videos. Algunos devuelven un 404 o una imagen diminuta de marcador de posición y el póster se ve roto. Consulta la página de prueba de disponibilidad de pósters si planeas usar max, y trata posterQuality="high" como el valor seguro por defecto.
Opción 2: auto-incrustar URLs de YouTube en MDX
El camino cómodo: pega una URL de YouTube en su propia línea y la integración la convierte en un embed. Menos escritura, pero añade una integración de compilación y sus restricciones de versión. Si solo incrustas videos de vez en cuando, la Opción 1 sigue siendo mi opción por defecto.
Instalación y configuración
npm i astro-embedLuego edita astro.config.mjs:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import embeds from 'astro-embed/integration';
export default defineConfig({
integrations: [embeds(), mdx()], // embeds BEFORE mdx()
});El orden de las integraciones importa
embeds() debe ir antes de mdx(). El orden inverso rompe los auto-embeds. Guías antiguas (incluida la primera versión de esta) mostraban embeds() después de mdx() porque eso decía la documentación en su momento. Si tu configuración está así, primero cambia el orden antes de depurar cualquier otra cosa.
Si no quieres que el matcher de Open Graph convierta cada URL https:// suelta en una vista previa de enlace, desactívalo:
export default defineConfig({
integrations: [
embeds({
services: {
LinkPreview: false,
},
}),
mdx(),
],
});El paquete independiente @astro-community/astro-embed-integration sigue existiendo y funciona, pero el camino documentado ahora es la exportación de subruta de astro-embed, así que usa astro-embed/integration salvo que tengas un motivo para no hacerlo.
Compatibilidad de versiones de Astro
Esta es la parte que muerde a la gente. @astro-community/astro-embed-integration@0.13.0 (publicada el 2026-08-27) declara una peer dependency de astro: ^7.2.4. Esa versión añadió soporte para el nuevo procesador MDX de Astro y es un breaking change para la integración de auto-embed.
| Astro | componentes de astro-embed | integración de auto-embed |
|---|---|---|
| 7.2.4+ (actual 7.3.5) | la última (astro-embed@0.14.0) |
la última (astro-embed/integration, 0.13.0+) |
| 7.0 a 7.2.3 | astro-embed@0.13.1+ (el soporte de Astro 7 llegó el 2026-07-02) |
fija la integración a <=0.12.x |
| 5 / 6 | funciona (rango de peers `^5 |
Astro 7.2.4 o superior
npm i astro-embedUsa el fragmento de configuración de arriba con import embeds from 'astro-embed/integration'.
Astro anterior (fíjala)
npm i @astro-community/astro-embed-integration@^0.12E impórtala como import embeds from '@astro-community/astro-embed-integration'. Mantén embeds() antes de mdx() independientemente de la versión.
Con npm 7 o superior y --strict-peer-deps, una instalación con versiones incompatibles falla directamente. Las instalaciones normales normalmente solo avisan, que es como una combinación rota se cuela en CI. Si estás en Astro 5 o 6, fijar <=0.12.x es el camino previsto (conviene confirmarlo en tu proyecto exacto con npm ls astro-embed antes de confiarlo a un pipeline).
¿Tienes curiosidad por saber qué te aporta la actualización a Astro 7 en velocidad de compilación? Mira los benchmarks de compilación de Astro 7 de un sitio de 743 páginas.
Si vienes de la configuración de 2022
Si seguiste la versión original de esta guía, revisa dos cosas tras actualizar: la ruta de importación de la integración (astro-embed/integration) y el orden de las integraciones (embeds() antes de mdx()). Ambas cambiaron.
Uso
Pega una URL de YouTube en su propia línea en tu archivo MDX. Sin importación:
---
title: "My Post"
---
Check out this video:
https://youtu.be/NkShQ1wwiCg
The integration converts it to a <YouTube> component automatically.La URL debe estar en su propia línea. Una URL en medio de una frase se queda como enlace normal. El mismo matcher funciona para Vimeo, posts de Twitter/X, posts de Mastodon, posts de Bluesky, GitHub Gists y vistas previas de enlaces de Open Graph.
Servicios soportados
astro-embed es más que un envoltorio de YouTube. Todo lo que exporta:
- YouTube:
<YouTube> - Vimeo:
<Vimeo> - Twitter/X:
<Tweet> - Mastodon:
<MastodonPost> - Bluesky:
<BlueskyPost>(HTML estático, cero JS del lado del cliente) - GitHub Gist:
<Gist> - Estado de Baseline:
<BaselineStatus> - Open Graph:
<LinkPreview>
Importa lo que necesites desde un solo lugar:
import { YouTube, Vimeo, Tweet, MastodonPost, BlueskyPost, Gist, LinkPreview } from "astro-embed";El repositorio de GitHub se movió a delucis/astro-embed (antes estaba bajo la organización astro-community). El scope de npm sigue siendo @astro-community/*, así que tus instalaciones y tu lockfile no se ven afectados. Actualiza los marcadores antiguos y sigue adelante.
El clic reproduce con autoplay
Hacer clic en la fachada inicia la reproducción de inmediato. lite-youtube fuerza autoplay=1 a través de la YouTube Player API al hacer clic. Es deliberado: evita el antiguo bug del doble clic para reproducir (corregido en lite-yt v0.3.0, 2023-10-04).
Clic = autoplay
Clic significa reproducir. No hay un estado intermedio de «reproductor cargado, en pausa». Si incrustas tutoriales largos donde preferirías que el video espere, tenlo en cuenta antes de publicar.
Puedes pasar parámetros del reproductor de YouTube a través de params, así que params="autoplay=0" parece la solución obvia. No he verificado que eso anule el autoplay forzado en la versión actual de lite-yt, así que no prometas ese comportamiento en tu contenido. Pruébalo en local si el clic-para-pausar te importa.
Imágenes de póster y privacidad
El iframe es la parte pesada que arrastra cookies, y la fachada lo maneja bien: la reproducción pasa por youtube-nocookie.com. El póster es otra historia.
Por defecto, el póster se enlaza directamente desde https://i.ytimg.com/vi/<id>/hqdefault.jpg (480px). Eso es una solicitud a servidores de Google en cada carga de página, antes de cualquier clic. youtube-nocookie.com solo aplica al iframe. Si tienes una configuración estricta de GDPR, aloja la miniatura tú mismo y pásala:
<YouTube id="NkShQ1wwiCg" poster="/images/posters/NkShQ1wwiCg.webp" />Dos notas más sobre el póster:
- Desde lite-yt v0.3.1 (2024-03-04) el elemento mejora el póster a un WebP de mayor resolución cuando hay uno disponible.
posterQuality="max"descargamaxresdefault.jpg, que no existe para todos los videos.highes el valor seguro por defecto.
Nota sobre GDPR
El póster enlazado por defecto desde i.ytimg.com sigue siendo una solicitud a Google al cargar la página. Para configuraciones estrictas, pasa una imagen autoalojada mediante la prop poster y evita por completo la solicitud a terceros.
Si prefieres mantener el póster en tu propia CDN, sírvelo desde Bunny CDN y pasa la URL a poster. Y si estás listo para abandonar YouTube por completo, puedes alojar videos con Bunny Stream en lugar de YouTube o Vimeo.
Comprobación de realidad en costes y operaciones: cada embed añade una solicitud de imagen más unos pocos KB de CSS y JavaScript de la fachada. El reproductor pesado solo se carga al hacer clic. Sin coste de servidor, sin piezas móviles extra en tu despliegue.
Verifica que tu embed funciona
La versión original de esta guía se detenía en la instalación. No lo hagas. Después de compilar, confirma que la fachada se incluyó y que ningún iframe de YouTube está presente en el HTML inicial:
npm run build
grep -l "lite-youtube" dist/**/*.html # should match pages with embeds
grep -L "youtube.com/embed" dist/**/*.html # iframe must NOT ship pre-clickEl primer comando debería listar todas las páginas que tienen un video. El segundo lista los archivos que no contienen un iframe previo al clic; todas las páginas con embed deberían aparecer ahí. Si una página falta en esa segunda lista, el iframe se incluyó en el HTML inicial y has vuelto al camino lento.
Luego prueba el clic en el navegador:
- Marcado de la fachada presente en el HTML generado (etiqueta
lite-youtubeencontrada) - Ninguna solicitud a
youtube.com/embeden la carga inicial de la página - El póster se renderiza con un botón de reproducción
- El clic carga el reproductor desde
youtube-nocookie.com(y reproduce automáticamente) - Opcional: Lighthouse antes/después en Core Web Vitals y LCP
Las flags de grep y el globbing con ** difieren en las shells de Windows. Ejecuta esto desde WSL o Git Bash si la salida se ve rara.
Ya que estás en la salida de la compilación: si te importan el número de páginas y el tiempo de compilación, hay una guía sobre cómo optimizar la velocidad de compilación de Astro y otra sobre cómo desplegar tu blog de Astro en Cloudflare cuando la salida esté limpia.
Por qué esto es más rápido que los embeds estándar
Un <iframe> normal de YouTube carga del orden de 1 a 2 MB de JavaScript al cargar la página (aproximado) aunque nadie reproduzca el video. Eso es lo que hunde las Core Web Vitals en posts con muchos videos.
El enfoque de astro-embed:
- Muestra una miniatura ligera (imagen de póster)
- No carga nada de JavaScript de YouTube inicialmente
- Carga el iframe completo solo cuando el usuario pulsa reproducir
- Usa
youtube-nocookie.compara la reproducción
El resultado: tu página carga rápido, Lighthouse se mantiene sano y los visitantes solo descargan los scripts de YouTube si quieren ver el video. La cifra de ~224x viene del README de lite-youtube (la comparación del propio Paul Irish), no de un benchmark que yo haya ejecutado.

Captura de una medición de 2022: embed con fachada frente a iframe estándar. Tanto las herramientas como el reproductor de YouTube han cambiado desde entonces. Vuelve a ejecutar Lighthouse en tu propia compilación para obtener cifras que correspondan a tu stack.
Usar embeds de YouTube en archivos .astro
También puedes usar astro-embed en archivos .astro, no solo en MDX. Es la jugada correcta para secciones hero, diseños con video destacado y cualquier componente reutilizable donde el ID del video venga de props o de un CMS:
---
import { YouTube } from "astro-embed";
---
<section>
<h2>Featured Video</h2>
<YouTube id="NkShQ1wwiCg" title="Featured tutorial" />
</section>Alternativa: usar lite-youtube-embed directamente
Si no quieres la dependencia de astro-embed en absoluto, usa lite-youtube-embed como un web component normal. Incluyes tú mismo su CSS y JavaScript (el README documenta las líneas exactas para bundlers o una etiqueta script simple), y luego renderizas:
<lite-youtube videoid="NkShQ1wwiCg" playlabel="Play"></lite-youtube>El README también documenta un patrón de mejora progresiva donde el marcado estático es un enlace real y funcional antes de que el JavaScript lo mejore.
Camino sin dependencias
Te saltas el paquete de Astro y toda la matriz de versiones. La contrapartida: gestionas la carga de recursos y las actualizaciones tú mismo en lugar de recibirlas de astro-embed.
Dos apuntes más. justinribeiro/lite-youtube es un port con shadow DOM de la misma idea y está recomendado en el README de Paul Irish. También existen ports para React (react-lite-youtube-embed 3.7.0, 2026-09-06, y @next/third-parties), pero son solo para React/Next e irrelevantes salvo que abandones Astro. Para el lado Markdown de Gatsby, mira cómo incrustar videos de YouTube en Gatsby MDX.
Solución de problemas
| Síntoma | Causa | Solución |
|---|---|---|
| El componente se renderiza como texto plano o nada | @astrojs/mdx no está instalado |
npx astro add mdx, luego reinicia el servidor de desarrollo |
Cannot find module 'astro-embed' |
Paquete no instalado, o ruta de importación incorrecta | Instala astro-embed (o el paquete independiente) y haz que la importación coincida con lo que instalaste |
| Las URLs de auto-embed se quedan como enlaces | Orden de integraciones incorrecto | embeds() debe ir antes de mdx() en astro.config.mjs |
| El reproductor muestra «Error 153» de YouTube | Política de referrer antigua de lite-youtube-embed | Actualiza a lite-youtube-embed >= 0.3.4 (incluido en astro-embed-youtube >= 0.5.10); el fix de la política de referrer se publicó el 2025-11-10 |
| Errores de peer dependencies de npm en Astro < 7.2.4 | La integración 0.13.x requiere astro: ^7.2.4 |
Fija @astro-community/astro-embed-integration@^0.12, o usa solo importaciones manuales |
posterQuality="max" muestra una caja en blanco o gris |
maxresdefault.jpg no existe para ese video |
Cambia a posterQuality="high" |
| Una URL dentro de una frase no se convierte | El auto-embed solo detecta URLs en su propia línea | Pon la URL en su propia línea, o usa <YouTube> manualmente |
Resumen
Los embeds de YouTube basados en fachada mantienen las páginas rápidas y las puntuaciones de Lighthouse honestas, y ponen la reproducción en youtube-nocookie.com. La actualización de 2026 de esta configuración se reduce sobre todo a tres cosas: importar desde astro-embed/integration, poner embeds() antes de mdx(), y comprobar que tu versión de Astro es 7.2.4 o superior antes de adoptar la última integración de auto-embed.
Si estás construyendo el sitio desde cero, las piezas complementarias son cómo añadir videos de YouTube a tu blog de Astro en SSG y SSR y cómo crear un blog de Astro gratis en 30 minutos.
¿Funciona esto con Astro SSR?
Sí. <YouTube> es un componente de Astro normal, así que funciona tanto con salida estática como con renderizado en servidor. El marcado de la fachada es el mismo en ambos casos; la única diferencia es cuándo se produce el HTML.
¿Puedo desactivar el autoplay al hacer clic?
lite-youtube fuerza autoplay=1 cuando el visitante pulsa reproducir. Pasar params="autoplay=0" parece la solución, pero no he verificado que anule el autoplay forzado en la versión actual de lite-yt. Si el clic-para-pausar es un requisito imprescindible, pruébalo en tu compilación antes de confiar en ello.
¿El auto-embed funciona también para Vimeo?
Sí. Una URL de Vimeo en su propia línea se convierte de la misma manera, y existe un componente <Vimeo> si prefieres las importaciones manuales. El matcher de auto-embed también cubre Twitter/X, Mastodon, Bluesky, Gists y vistas previas de enlaces de Open Graph.
Los precios de los VPS subieron en todos los proveedores en 2026. Si estás reconsiderando una máquina alquilada, mira qué cambió y cuándo gana un mini PC.


