---
title: "Cómo incrustar vídeos de YouTube en Gatsby (MDX + Markdown)"
description: "Aprende a incrustar vídeos de YouTube en Gatsby con plugins de Markdown, componentes MDX y fachadas lite-youtube rápidas. Incluye configuración con Contentful y consejos de RGPD."
date: 2026-09-26
categories: ["web-development"]
tags: ["gatsby","youtube","mdx"]
---

import Button from "@components/widgets/Button.astro";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";
import Tabs from "@components/widgets/Tabs.astro";
import Tab from "@components/widgets/Tab.astro";

Para incrustar vídeos de YouTube en Gatsby no basta con pegar un iframe en el Markdown. React elimina el HTML en bruto de la salida renderizada, así que el vídeo desaparece sin avisar y te queda un hueco vacío en la entrada. Necesitas un plugin que reescriba las URL de los vídeos en iframes durante la compilación, o un componente MDX que renderice el iframe directamente.

<Notice type="warning" title="Gatsby está en modo de mantenimiento">
  Gatsby está en modo de mantenimiento desde la adquisición por parte de Netlify en febrero de 2023. Las versiones publicadas desde entonces son solo correcciones de errores y soporte del runtime. El historial de versiones importa si vas a actualizar: **gatsby@5.16.0 (2026-01-26)** añadió soporte para React 19 y Node.js 24. **gatsby@5.16.1 (2026-02-10)** es una única corrección para las regresiones de la Gatsby Head API (`<title>` no actualizaba `document.title`). React 19 es opcional. Quedarse en React 18 está bien y es compatible. Si subes a React 19 con npm 7+, usa `npm install --legacy-peer-deps`, y ten en cuenta que Partial Hydration (experimental) es incompatible con React 19. El campo `engines` es `>=18.0.0 <26`, así que Node 24 funciona, pero Node 26 todavía no.

  Las instrucciones de abajo siguen funcionando para sitios Gatsby existentes (el ecosistema de plugins registra unas 3,4 mil instalaciones al mes frente al ~1,08 millones del núcleo de Gatsby). Si empiezas desde cero, elige otra cosa: mira [cómo añadir vídeos de YouTube a tu blog de Astro](/add-youtube-videos-astro-blog/), [crea un blog gratis con Astro y Cloudflare](/es/crear-blog-astro-gratis/), o si estás dejando WordPress, [la migración de WordPress a Astro y MDX](/es/migracion-wordpress-a-astro/). Para la elección del framework en sí, tanto [Next.js](https://nextjs.org/) como [Astro](https://astro.build/) son opciones razonables.
</Notice>

Todos los plugins de incrustación del nicho de Gatsby están desactualizados. `gatsby-remark-embed-video` es el caballo de batalla y no ha publicado nada desde 2022. Elige según tus necesidades de sintaxis y tu presupuesto de rendimiento, no según qué repositorio parezca vivo. Si controlas el contenido tú mismo, prefiere la ruta del componente o de la fachada que verás abajo.

Esta guía cubre cuatro enfoques: un plugin de remark para sintaxis con marcadores, un incrustador de URL directas, un componente MDX personalizado y una fachada con carga diferida. La fachada es la que yo usaría en un sitio nuevo.

## Antes de empezar: versiones y qué necesitas

<ListCheck>
<ul>
<li>Un sitio Gatsby 5 existente, o uno nuevo creado con `gatsby new`.</li>
<li>Node.js 18 a 24. Node 24 es compatible desde gatsby@5.16.0; el campo `engines` tiene un tope de `<26`.</li>
<li>npm 7 o superior (puede que necesites `--legacy-peer-deps` al subir a React 19).</li>
<li>Una fuente de contenido: archivos locales `.md` / `.mdx`, o un CMS headless con un campo de tipo **Markdown**.</li>
<li>Familiaridad con `gatsby clean`. La caché te dará problemas después de cambiar plugins.</li>
</ul>
</ListCheck>

Verifica antes de instalar nada:

```bash
node -v        # expect v18.x - v24.x
npm ls gatsby  # expect gatsby@5.x
```

Los plugins de remark del equipo de Gatsby se versionan al unísono con el núcleo y recibieron el aumento de la peer-dep de React 19 el 2026-01-26: `gatsby-transformer-remark` 6.16.0, `gatsby-remark-responsive-iframe` 6.16.0, `gatsby-plugin-mdx` 5.16.0. Los fragmentos de instalación de abajo los traen automáticamente.

Una nota al pie que ahorra confusiones: la pila MDX de Gatsby es **MDX v2** (`@mdx-js/mdx ^2.3.0`), no v3. No copies sintaxis de MDX v3 de otros blogs en un proyecto Gatsby.

## Opción 1: gatsby-remark-embed-video (Markdown y MDX)

[gatsby-remark-embed-video](https://www.gatsbyjs.com/plugins/gatsby-remark-embed-video/) es el caballo de batalla para la sintaxis de marcadores `` `youtube:` ``. Es compatible con YouTube, Vimeo, VideoPress y Twitch, y funciona tanto con `gatsby-transformer-remark` (Markdown plano) como con `gatsby-plugin-mdx`.

Ten claro lo que estás adoptando: la v3.2.1 se publicó el 2022-06-30, el último push del repositorio fue el 2023-03-01, y aun así sigue registrando unas 3,4 mil descargas al mes. Funciona con Gatsby 5 (los ejemplos de configuración actuales del README apuntan a Gatsby 5), pero nadie está lanzando funcionalidades. Elígelo por la sintaxis de marcadores y los flujos de trabajo con CMS, no por su velocidad de mantenimiento.

### Instalación

```bash
npm i gatsby-remark-embed-video gatsby-transformer-remark
```

Si quieres iframes responsivos (recomendado), instala también:

```bash
npm i gatsby-remark-responsive-iframe
```

En Gatsby 5.16 con React 19, si npm informa de conflictos de peer-deps:

```bash
npm install --legacy-peer-deps gatsby-remark-embed-video gatsby-transformer-remark gatsby-remark-responsive-iframe
```

### Configuración para Markdown (gatsby-transformer-remark)

Añade esto a tu `gatsby-config.js`:

```javascript
{
  resolve: "gatsby-transformer-remark",
  options: {
    plugins: [
      {
        resolve: "gatsby-remark-embed-video",
        options: {
          width: 800,
          ratio: 1.77,           // 16/9 aspect ratio
          height: 400,           // overrides ratio if set
          related: false,        // rel=0: end-screen related videos limited to the same channel
          noIframeBorder: true,
          loadingStrategy: "lazy",
          containerClass: "embedVideo-container",
          urlOverrides: [
            {
              id: "youtube",
              embedURL: (videoId) =>
                `https://www.youtube-nocookie.com/embed/${videoId}`,
            },
          ],
        },
      },
      "gatsby-remark-responsive-iframe",  // must come after embed-video
    ],
  },
},
```

La sobrescritura de la URL con `youtube-nocookie.com` usa el modo de privacidad mejorada de YouTube. Sin cookies hasta que el usuario pulsa reproducir. Un buen valor predeterminado para audiencias sensibles al RGPD.

**Verificación:** `gatsby develop`, abre una entrada con una etiqueta de vídeo y comprueba en DevTools (pestaña Elements) que aparece `<iframe src="https://www.youtube-nocookie.com/embed/...">`. Si el iframe no está, salta a [Solución de problemas](#solución-de-problemas).

### Configuración para MDX (gatsby-plugin-mdx)

Si usas MDX en lugar de Markdown plano:

```javascript
{
  resolve: "gatsby-plugin-mdx",
  options: {
    gatsbyRemarkPlugins: [
      {
        resolve: "gatsby-remark-embed-video",
        options: {
          width: 800,
          ratio: 1.77,
          related: false,
          noIframeBorder: true,
          loadingStrategy: "lazy",
        },
      },
      "gatsby-remark-responsive-iframe",
    ],
  },
},
```

`gatsby-plugin-mdx` 5.16.0 sigue fijando MDX v2. Consulta la nota de los requisitos previos de arriba si un fragmento que encontraste en línea usa sintaxis de MDX v3.

### Uso en el contenido

Añade estas etiquetas en su propia línea dentro de tus archivos Markdown o MDX:

```
`video: https://www.youtube.com/embed/2Xc9gXyf2G4`

`youtube: https://www.youtube.com/watch?v=2Xc9gXyf2G4`
`youtube: 2Xc9gXyf2G4`

`vimeo: https://vimeo.com/5299404`
`vimeo: 5299404`

`videoPress: https://videopress.com/v/kUJmAcSf`
`videoPress: kUJmAcSf`

`twitch: https://player.twitch.tv/?channel=dakotaz`
`twitch: https://player.twitch.tv/?autoplay=false&video=v273436948`
`twitch: 273436948`
`twitchLive: dakotaz`
```

También puedes añadir títulos de accesibilidad:

```
`youtube: [My Video Title](https://www.youtube.com/watch?v=2Xc9gXyf2G4)`
```

Una advertencia: el plugin analiza las URL mediante `get-video-id@^3.6.4`, y las URL de YouTube **Shorts con `/shorts/` no están verificadas** con ese analizador. Usa los formatos estándar `watch?v=` o `youtu.be` y no des por hecho que los enlaces de Shorts funcionan sin probar uno tú mismo.

**Verificación:** guarda una entrada con un marcador, ejecuta `gatsby develop` y confirma que el iframe se renderiza y se reproduce.

### Opciones del plugin que conviene conocer (y una que debes evitar)

El README documenta algunas opciones más allá de las básicas:

| Opción | Qué hace |
|---|---|
| `width` / `height` | Tamaño fijo del iframe en px. `height` tiene prioridad sobre `ratio` si se define. |
| `ratio` | Relación de aspecto como ancho/alto. `1.77` es 16:9. |
| `related` | `false` establece `rel=0`. Consulta la siguiente sección para saber qué hace ahora. |
| `noIframeBorder` | Elimina el atributo `border` del iframe. |
| `loadingStrategy` | `"lazy"` añade `loading="lazy"` al iframe. |
| `containerClass` | Nombre de clase en el `div` contenedor, útil para tu propio CSS responsivo. |
| `urlOverrides` | Reescribe la URL de incrustación por proveedor. Así es como obtienes `youtube-nocookie.com`. |
| `iframeId` | `true` establece el `id` del iframe con el ID del vídeo. **Obligatorio si quieres que la API del reproductor IFrame de YouTube** se comunique con tus incrustaciones (control de reproducción/pausa desde tus propios botones, eventos de progreso, etc.). |
| `sandbox` | Rota. Ver abajo. No la uses. |

<Notice type="error" title="No uses la opción sandbox (error del plugin n.º 200)">
  La opción `sandbox` serializa el valor mal: solo se renderiza el **primer token**. Configurar `sandbox: 'allow-same-origin allow-scripts allow-presentation'` produce `sandbox="allow-same-origin"`, lo que bloquea los scripts y rompe la reproducción sin avisar. Es el [issue #200](https://github.com/borgfriend/gatsby-remark-embed-video/issues/200), abierto desde el 2023-12-16 sin corrección publicada. Omite la opción por completo. Si de verdad necesitas un iframe con sandbox, usa la Opción 2 o 3 de abajo, donde controlas el atributo tú mismo.
</Notice>

### Parámetros del reproductor de YouTube que siguen funcionando

El comentario sobre `related: false` en los tutoriales antiguos es engañoso. Desde el cambio de YouTube del 25 de septiembre de 2018, `rel=0` **no** oculta los vídeos relacionados. Limita las sugerencias de la pantalla final a vídeos **del mismo canal**. Ya no puedes suprimirlas por completo.

Algunos parámetros que seguirás encontrando en entradas de blog son callejones sin salida. Según la [documentación oficial de la API del reproductor IFrame de YouTube](https://developers.google.com/youtube/player_parameters) (consultada el 2026-09-25):

| Parámetro | Estado |
|---|---|
| `rel=0` | Funciona. Vídeos relacionados del mismo canal al final, no «ninguno». |
| `playsinline=1` | Funciona. Reproducción en línea en iOS en lugar de tomar toda la pantalla. Vale la pena añadirlo. |
| `autoplay`, `mute`, `start`, `end`, `controls`, `loop`, `playlist` | Siguen funcionando. |
| `modestbranding`, `showinfo`, `autohide`, `theme` | Obsoletos y sin efecto. No los copies a `urlOverrides` ni a las URL de tus componentes. |

Si quieres `playsinline=1` con la Opción 1, añádelo dentro de la cadena de plantilla de `urlOverrides`:

```javascript
urlOverrides: [
  {
    id: "youtube",
    embedURL: (videoId) =>
      `https://www.youtube-nocookie.com/embed/${videoId}?playsinline=1`,
  },
],
```

### Uso con Contentful CMS

Este enfoque funciona con Contentful o cualquier CMS headless que genere Markdown. El único requisito: **tu campo de contenido debe ser de tipo Markdown, no texto enriquecido.**

En Contentful, crea un campo de texto de tipo «Markdown». Después añade la etiqueta de vídeo en su propia línea en el editor:

```
`youtube: https://youtu.be/2Wmats7Q6ck`
```

Cuando Gatsby compila, `gatsby-transformer-remark` procesa el Markdown y el plugin embed-video convierte la etiqueta en un iframe.

Si los editores ponen vídeos en un campo de **texto enriquecido** de Contentful, nada de esto se activa. El texto enriquecido nunca entra en la canalización de remark. Esas entradas necesitan el renderizador de texto enriquecido de Contentful con un resolvedor de entradas incrustadas, que es una configuración completamente distinta. Si aún estás eligiendo un CMS, tengo un repaso de las [mejores opciones de CMS headless](/best-headless-cms-for-astro/) que cubre cuáles te entregan Markdown y cuáles no.

**Verificación:** añade un vídeo en Contentful, ejecuta `gatsby build` y busca el host de incrustación en la salida:

```bash
grep -r "youtube-nocookie.com/embed" public/ | head
```

Si grep no encuentra nada, el campo es casi con seguridad de texto enriquecido.

### Importante: el orden de los plugins importa

Si usas `gatsby-remark-responsive-iframe`, `gatsby-remark-images` o `gatsby-remark-prismjs`, el plugin embed-video debe ir primero:

```javascript
plugins: [
  "gatsby-remark-embed-video",
  "gatsby-remark-responsive-iframe",
  "gatsby-remark-prismjs",
  "gatsby-remark-images",
]
```

Un orden incorrecto rompe la incrustación. Si responsive-iframe se ejecuta primero, el iframe del vídeo ya está en el AST y queda destrozado o se omite. Esta es la segunda razón más común de que «la etiqueta de vídeo no haga nada».

## Opción 1b: incrustaciones pegando la URL con gatsby-remark-embedder

[gatsby-remark-embedder](https://github.com/MichaelDeBoey/gatsby-remark-embedder) es la alternativa si la sintaxis de marcadores resulta demasiado engorrosa para tus editores. Pegas una **URL directa en su propia línea**, rodeada de líneas en blanco, y el plugin la convierte en una incrustación durante la compilación. Sin prefijo `youtube:`.

```
Some intro text.

https://www.youtube.com/watch?v=2Xc9gXyf2G4

More text.
```

Acepta los formatos `watch?v=` y `youtu.be`. Dos detalles lo hacen atractivo:

- Su transformador de YouTube **ya emite `youtube-nocookie.com` con `rel=0` por defecto**. La configuración de privacidad para la que la Opción 1 necesita `urlOverrides` viene gratis aquí.
- Incluye transformadores para muchos más servicios: CodePen, CodeSandbox, GIPHY, Instagram, Lichess, Pinterest, Slides, SoundCloud, Spotify, Streamable, Twitch, Twitter/X y más.

```bash
npm i gatsby-remark-embedder
```

```javascript
// gatsby-config.js
{
  resolve: "gatsby-transformer-remark",   // or gatsby-plugin-mdx via gatsbyRemarkPlugins
  options: {
    plugins: ["gatsby-remark-embedder"],
  },
},
```

Nota de versión: v7.0.0 (2023-05-30), peer dep `gatsby ^5`, inactivo como todo lo demás aquí.

Una salvedad operativa: algunos transformadores descargan HTML remoto durante la compilación (`node-fetch` / `fetch-retry`). El de YouTube se basa en plantillas, así que es seguro sin conexión. El de Twitter/X no lo es. Si compilas en una CI con conexión inestable o aislada, prueba una compilación completa antes de comprometerte con este plugin.

## Opción 2: componente React de YouTube personalizado para MDX

Si escribes el contenido directamente en MDX y quieres control total, sáltate el plugin y crea un componente de YouTube:

```jsx
// src/components/YouTube.js
const YouTube = ({ id, title = "YouTube video" }) => (
  <div style={{ position: "relative", paddingBottom: "56.25%", height: 0, overflow: "hidden" }}>
    <iframe
      src={`https://www.youtube-nocookie.com/embed/${id}?playsinline=1`}
      title={title}
      style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }}
      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
      allowFullScreen
      loading="lazy"
    />
  </div>
);

export default YouTube;
```

Después impórtalo y úsalo en tus archivos MDX:

```mdx
import YouTube from "../components/YouTube";

# My Post

Some content here.

<YouTube id="2Xc9gXyf2G4" title="Demo video" />
```

El contenedor con `paddingBottom: 56.25%` para 16:9 es el truco estándar de incrustación responsiva. La caja mantiene su relación de aspecto en cualquier ancho de contenedor. Uso la misma técnica en [incrustaciones responsivas de YouTube en Astro MDX](/responsive-youtube-astrojs/) si quieres la versión multi-framework.

Lo que obtienes: control total sobre los atributos del iframe (incluido un `sandbox` de verdad si lo necesitas), sin dependencia de plugins y con `loading="lazy"` en el iframe. El precio es el alcance: esto solo funciona donde escribes MDX tú mismo. Un campo Markdown de un CMS no ejecutará tus imports.

**Verificación:** renderiza la página MDX, confirma el iframe y `loading="lazy"` en DevTools, luego redimensiona la ventana y comprueba que la caja mantiene el 16:9.

## Opción 3: carga diferida de vídeos de YouTube con una fachada lite-youtube

El enfoque del iframe en tiempo de compilación sigue cargando el JavaScript del reproductor de YouTube en cada visita, incluso cuando el lector nunca pulsa reproducir. Eso perjudica las Core Web Vitals y es el valor predeterminado equivocado si los vídeos quedan por debajo del pliegue.

El patrón de fachada lo soluciona: primero renderiza una imagen de póster y un botón de reproducción, y carga el iframe real **solo al hacer clic**. Al cargar la página solo descargas un JPEG y nada de `youtube.com`. El paquete mantenido en este espacio, [paulirish/lite-youtube-embed](https://github.com/paulirish/lite-youtube-embed) (6.349 estrellas), documenta el efecto como «aproximadamente 224 veces más rápido» que una incrustación real. No he medido una cifra en MB y no voy a inventarla. Abre DevTools en cualquier incrustación de YouTube y mira la pestaña de red tú mismo.

Tres formas de hacerlo en Gatsby:

<Tabs>
<Tab name="lite-youtube-embed">
```bash
npm i lite-youtube-embed
```

```jsx
// src/components/YouTubeLite.js
import "lite-youtube-embed/src/lite-yt-embed.css";
import "lite-youtube-embed";

const YouTubeLite = ({ id, title }) => (
  <lite-youtube videoid={id} playlabel={title}></lite-youtube>
);

export default YouTubeLite;
```

Usa `youtube-nocookie.com` por defecto y admite imágenes de póster personalizadas. Elígela si quieres la fachada más conocida con el menor esfuerzo.

</Tab>
<Tab name="justinribeiro/lite-youtube">
Es un web component de Shadow DOM sin dependencias ([repo](https://github.com/justinribeiro/lite-youtube), último push el 2026-04-21). Carga el archivo único del componente una vez en tu layout (cópialo en `src/components/` o sácalo de una CDN) y luego úsalo en MDX como cualquier elemento:

```html
<lite-youtube
  videoid="2Xc9gXyf2G4"
  videotitle="Demo video"
  nocookie
  autoload
></lite-youtube>
```

Atributos útiles: `nocookie`, `autoload` (carga diferida al hacer scroll basada en IntersectionObserver), `videotitle` para ARIA, `playlistid`, y un atributo `short` para YouTube Shorts que es **experimental**. No confíes en él en producción todavía. El póster es WebP con un JPEG de respaldo, y las versiones recientes admiten un nonce de CSP. Elígelo si quieres carga activada por scroll o tienes una CSP estricta.

</Tab>
<Tab name="Fachada React hecha a mano">
Cero dependencias y controlas cada atributo. Mantén el contenedor 16:9 de la Opción 2 alrededor de este componente:

```jsx
// src/components/YouTubeFacade.js: poster first, iframe on click
import { useEffect, useRef, useState } from "react";

const YouTubeFacade = ({ id, title = "YouTube video" }) => {
  const [play, setPlay] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (play && ref.current) ref.current.focus();
  }, [play]);
  return play ? (
    <iframe
      src={`https://www.youtube-nocookie.com/embed/${id}?autoplay=1&playsinline=1`}
      title={title}
      ref={ref}
      style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}
      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
      allowFullScreen
    />
  ) : (
    <button
      type="button"
      onClick={() => setPlay(true)}
      aria-label={`Play video: ${title}`}
      style={{ position: "absolute", inset: 0, width: "100%", height: "100%", padding: 0, border: 0, cursor: "pointer",
               background: `center / cover no-repeat url(https://i.ytimg.com/vi/${id}/hqdefault.jpg)` }}
    />
  );
};

export default YouTubeFacade;
```

Elígela si quieres cero dependencias y necesitas conectar tu propia lógica de analítica o de consentimiento al evento de clic.

</Tab>
</Tabs>

Cómo se comporta la fachada en tiempo de ejecución: al cargar la página solo se descarga el JPEG del póster. Ninguna petición a `youtube.com` ni a `googlevideo.com`. Tras el clic, aparece el iframe con `autoplay=1` y el JavaScript del reproductor se carga en ese momento.

Dos modos de fallo que conviene conocer antes de publicar esto:

- **Errores 404 del póster.** Usa `https://i.ytimg.com/vi/<ID>/hqdefault.jpg`. Esa siempre se resuelve. `maxresdefault.jpg` devuelve 404 en algunos vídeos y te queda una caja negra.
- **URL de Shorts.** El soporte en `lite-youtube` de justinribeiro es experimental. Pruébalo antes de prometérselo a los editores.

Si prefieres no incrustar el reproductor de nadie y quieres controlar la distribución (o servir vídeo fuera de YouTube por privacidad o monetización), mira [cómo alojar y distribuir vídeos sin YouTube ni Vimeo](/es/guia-bunny-stream/). Para la parte de distribución, [Bunny.net CDN](https://go.bitdoze.com/bunny) es lo primero que yo presupuestaría.

**Verificación:** pestaña Network de DevTools al cargar la página. Espera **cero** peticiones a `youtube.com` o `googlevideo.com` antes del clic. Tras el clic, aparece el JS del reproductor y el vídeo se reproduce. Opcional: ejecuta Lighthouse antes y después y compara el LCP.

## ¿Qué enfoque deberías elegir?

Todos los plugins de este nicho están desactualizados, así que elige por necesidades de sintaxis y presupuesto de rendimiento, no por cadencia de mantenimiento.

<ListCheck>
<ul>
<li>El contenido está en un CMS o en Markdown plano con etiquetas `youtube:` ya existentes: Opción 1.</li>
<li>Los editores pegan URL y odian los marcadores: Opción 1b.</li>
<li>Escribes MDX y te importan los atributos del iframe: Opción 2.</li>
<li>El LCP está en rojo en PageSpeed Insights y los vídeos quedan por debajo del pliegue: Opción 3.</li>
</ul>
</ListCheck>

| Situación | Mejor opción | Por qué |
|---|---|---|
| CMS headless (Contentful, Sanity) con campos Markdown; editores no técnicos | Opción 1 o 1b | La transformación ocurre en la compilación; los editores nunca tocan JSX |
| Contenido MDX local, quieres control total sobre el iframe | Opción 2 | Cero dependencia de plugins, el marcado es tuyo |
| Importa el presupuesto de rendimiento, vídeos por debajo del pliegue | Opción 3 | El JS del reproductor solo se carga al hacer clic |
| Estás empezando un sitio nuevo en 2026 | No Gatsby | Una fachada sin framework sobrevive a cualquier migración. Mira la [comparación de Astro vs Next.js vs TanStack Start](/astro-vs-nextjs-vs-tanstack-start-which-wins/) |

Para un sitio Gatsby heredado con un CMS detrás, la Opción 1 es la opción aburrida y correcta. Para cualquier cosa nueva, yo construiría el componente de fachada y lo alojaría en Astro o Next.js.

## Solución de problemas

**¿No aparecen los vídeos?** Comprueba que tu campo de contenido sea de tipo Markdown, no texto enriquecido. El texto enriquecido en Contentful usa una canalización de renderizado distinta que se salta por completo los plugins de remark.

**¿Errores de compilación tras instalar?** Limpia la caché de Gatsby:

```bash
gatsby clean && gatsby develop
```

**¿Conflictos de plugins?** Asegúrate de que `gatsby-remark-embed-video` aparezca antes que cualquier otro plugin de remark en tu configuración. Si `gatsby-remark-responsive-iframe` se ejecuta primero, el iframe del vídeo ya está en el AST y queda destrozado o se omite.

**¿Configuraste `sandbox` y se rompió la reproducción?** Es el error del plugin [#200](https://github.com/borgfriend/gatsby-remark-embed-video/issues/200). Solo se renderiza el primer token de `sandbox`, así que `allow-scripts` se pierde y el reproductor queda muerto. Quita la opción. Si necesitas sandbox, usa el componente de la Opción 2 o 3, donde controlas el atributo.

**¿Siguen apareciendo vídeos relacionados al final?** Es lo esperado desde 2018. `rel=0` solo limita las sugerencias de la pantalla final al mismo canal. No existe ningún parámetro que las elimine.

**¿Errores de peer-dep de npm en Gatsby 5.16 / React 19?** React 19 es opcional. O te quedas en React 18, o instalas con `npm install --legacy-peer-deps`. Partial Hydration (experimental) no funciona con React 19. Desactiva una cosa o la otra.

**¿El póster de la fachada no carga?** Probablemente estás usando `maxresdefault.jpg`. Cambia a `hqdefault.jpg`. Siempre se resuelve.

**¿Las incrustaciones fallan en CI con gatsby-remark-embedder?** Algunos de sus transformadores descargan HTML remoto durante la compilación (Twitter/X es el culpable habitual). El transformador de YouTube se basa en plantillas y es seguro sin conexión. Identifica qué transformador necesita la red y elimina los demás si tu CI está bloqueada.

## Preguntas frecuentes

<Accordion label="¿Sigue funcionando con Gatsby 5 y Gatsby 5.16?" group="faq" expanded="true">
Sí. `gatsby-remark-embed-video` está desactualizado (v3.2.1, 2022) pero funciona en Gatsby 5. Los ejemplos actuales del README apuntan a Gatsby 5 y el plugin sigue registrando unas 3,4 mil instalaciones al mes. Dicho esto, la última versión es anterior a los cambios de Gatsby 5.16 / React 19, así que haz una prueba de humo con una instalación nueva en tu versión de Node antes de confiar en él para todo un conjunto de contenido. Limpia la caché después de instalar.
</Accordion>

<Accordion label="¿Necesito un plugin si uso MDX?" group="faq">
No. Si escribes el contenido como archivos MDX tú mismo, las Opciones 2 y 3 se saltan por completo la capa de plugins y te dan control total sobre el iframe (incluido un atributo `sandbox` que funciona). El plugin existe para los campos Markdown y los flujos de trabajo con CMS, donde los editores pegan URL o marcadores y no pueden escribir JSX.
</Accordion>

<Accordion label="¿Es youtube-nocookie suficiente para el RGPD?" group="faq">
Es un buen valor predeterminado, no una respuesta completa. `youtube-nocookie.com` retrasa las cookies hasta que el usuario pulsa reproducir. Suele ser suficiente para un blog personal y es mucho mejor que una incrustación directa de `youtube.com`. Para una configuración estricta con modo de consentimiento, necesitas una fachada de carga al hacer clic (Opción 3) para que no haya ninguna petición a terceros antes del consentimiento, y aun así habla con quien gestione tu cumplimiento normativo.
</Accordion>

<Accordion label="¿Puedo usar carga diferida sin un paquete de fachada?" group="faq">
Parcialmente. `loading="lazy"` en el iframe (el `loadingStrategy` de la Opción 1 o el atributo de la Opción 2) indica al navegador que difiera el iframe hasta que se acerque al viewport, pero una vez cargado, el JavaScript del reproductor de YouTube llega igualmente por completo. Una fachada evita el JS del reproductor por completo hasta el clic. Si el problema es el LCP, `loading="lazy"` por sí solo no lo arreglará en incrustaciones de vídeo por debajo del pliegue.
</Accordion>

Si quieres profundizar en el framework en sí, aquí están los [mejores cursos en línea de Gatsby.js](/gatsby-js-online-courses/) que he revisado.

<Button link="https://go.bitdoze.com/do" text="DigitalOcean $100 gratis" />
<Button link="https://go.bitdoze.com/vultr" text="Vultr $100 gratis" />
<Button link="https://go.bitdoze.com/hetzner" text="Hetzner 20 € gratis" />
<Button link="https://go.bitdoze.com/hostinger-vps" text="Hostinger VPS" />
_Los precios de los VPS subieron en todos los proveedores en 2026. Si estás replanteándote un servidor alquilado, mira [qué cambió y cuándo gana un mini PC](/vps-price-increases/)._