YouTube Embeds
Incrustar un <iframe> de YouTube directamente en un post cargaría ~700 KB de JavaScript, bloquearía el renderizado y dispararía peticiones de tracking antes de que el usuario hiciera nada. Usamos lite-youtube para evitar todo eso.
Análisis de Rendimiento
iframe nativo
- ~700 KB de JS descargado por video
- Bloquea el hilo principal repetidamente
- Scripts de tracking disparados de inmediato
- Retrasa severamente el LCP de la página
lite-youtube (Nyuseek)
- ~5 KB total en toda la página
- Solo carga una miniatura estática inicial
- Cero ejecución JS hasta la interacción
- Impacto nulo en métricas Core Web Vitals
Mecanismo de Inserción
El editor (Tiptap) agrega automáticamente el atributo data-embed="true" al enlace cuando el redactor usa el botón de "Insertar video". El HTML que se guarda en la base de datos tiene esta forma:
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" data-embed="true">
[Rick Astley - Never Gonna Give You Up]
</a>data-embed="true" es estricto para YouTube. Sin él, el enlace se trata como un hipervínculo estándar. Esto permite mencionar un video en texto sin forzar su incrustación visual.Formatos Soportados
| Formato | Ejemplo de URL | Estado |
|---|---|---|
| Watch estándar | youtube.com/watch?v=ID | Soportado |
| URL corta | youtu.be/ID | Soportado |
| Shorts | youtube.com/shorts/ID | Soportado |
| Live | youtube.com/live/ID | Soportado |
| URL con timestamp | youtube.com/watch?v=ID&t=120s | Soportado (Extrae ID) |
Instalación de Dependencias
Instalar Web Component
Para implementar este sistema necesitas instalar el paquete de lite-youtube:
Pipeline de Renderizado (SSR)
Carga Inicial HTML
El SSR recibe el HTML del post tal como está guardado en la base de datos.
Detección Regex
Busca todos los <a> que tengan data-embed="true" y una URL de YouTube, extrayendo el ID.
Reemplazo Estático
Sustituye el enlace por el Web Component <lite-youtube> en el servidor (cero fetch).
Hidratación Condicional
El script de lite-youtube se inyecta en el cliente solo si la bandera hasYoutube es verdadera.
Expresiones Regulares Core
Para asegurar que atrapamos el enlace sin importar el orden de los atributos (que puede variar según el editor):
// data-embed ANTES del href
const youtubeEmbedRegex = /(?:<p>)?\s*<a\s+(?:[^>]*?\s+)?data-embed=["']true["']
(?:[^>]*?\s+)?href=["'](URL_REGEX)["'][^>]*>\[([^\]]+)\]<\/a>\s*(?:<\/p>)?/gi;
// href ANTES del data-embed
const youtubeEmbedRegex2 = /(?:<p>)?\s*<a\s+(?:[^>]*?\s+)?href=["'](URL_REGEX)["']
(?:[^>]*?\s+)?data-embed=["']true["'][^>]*>\[([^\]]+)\]<\/a>\s*(?:<\/p>)?/gi;El identificador siempre corresponde al grupo de captura 2 (11 caracteres):
([a-zA-Z0-9_-]{11})Output Final Renderizado
<div class="my-8 rounded-3xl overflow-hidden shadow-sm border border-surface-100 bg-surface-50">
<lite-youtube videoid="dQw4w9WgXcQ"></lite-youtube>
</div>Y la inyección de script única en el footer del layout:
{hasYoutube && <script>import '@justinribeiro/lite-youtube';</script>}Diagnóstico de Errores Comunes
El video aparece como un simple enlace
Causa: Falta data-embed="true" en la DB.
No carga la miniatura (Espacio en blanco)
Causa: El Web Component no se hidrató.
hasYoutube se está activando y el script importado no esté bloqueado.Muestra imagen por defecto gris
Causa: El Regex falló en aislar exactamente 11 caracteres para el ID.
videoid="" resultante en el DOM para corregir la extracción.