Para diseñadores y webs de clientes

El widget de vibedom

Un botón flotante con la identidad sonora de una web. La semilla va dentro del snippet: no hay llamadas a la IA, ni base de datos, ni coste por visitante. El audio solo se descarga cuando alguien pulsa play.

1. Pega el snippet

Genera una semilla en el playground y copia el código que aparece en «Tu widget embebible». Debe quedar así, antes de </body>:

HTML
<!-- vibedom: música generativa de tu web -->
<script src="https://vibedom.dev/widget.js"
        data-seed="eyJtZXRhZGF0YSI6eyJ1cmwiOiJodHRwczovL25lb24tZ3JpZC5leGFtcGxlIiwiZGV0ZWN0ZWRWaWJlIjoiQ3liZXJwdW5rOiB0w6ljbmljbywgbm9jdHVybm8geSBuZcOzbiIsImV4cGxhbmF0aW9uIjoiRm9uZG8gbmVncm8gcHVybywgYWNlbnRvcyB2ZXJkZSBuZcOzbiB5IHRpcG9ncmFmw61hIG1vbm9zcGFjZSB0cmFkdWNpZG9zIGEgUmUgZnJpZ2lvIGdyYXZlLCBzaWVycmFzIGRlc2FmaW5hZGFzIHRyYXMgdW4gZmlsdHJvIGNlcnJhZG8geSB1biBhcnBlZ2lvIGRlIGVjbyBxdWUgcmVjdWVyZGEgYSBkYXRvcyBmbHV5ZW5kby4ifSwidWlUaGVtZSI6eyJiYWNrZ3JvdW5kQ29sb3IiOiIjMEEwQTBBIiwiYWNjZW50Q29sb3IiOiIjMDBGRjY2IiwidGV4dENvbG9yIjoiI0U2RkZFOSIsImZvbnRGYW1pbHkiOiJtb25vc3BhY2UifSwibXVzaWNhbFBhcmFtcyI6eyJicG0iOjg0LCJyb290Tm90ZSI6IkQiLCJzY2FsZSI6InBocnlnaWFuIiwib2N0YXZlIjozfSwic3ludGhDb25maWciOnsicGFkIjp7IndhdmVmb3JtIjoic2F3dG9vdGgiLCJhdHRhY2siOjIuNSwicmVsZWFzZSI6NCwiZmlsdGVyRnJlcSI6NTIwfSwiYXJwIjp7ImVuYWJsZWQiOnRydWUsIndhdmVmb3JtIjoic3F1YXJlIiwiZGVuc2l0eSI6MC40NSwiZGVsYXlXZXQiOjAuNTV9LCJlZmZlY3RzIjp7InJldmVyYkRlY2F5Ijo1LjUsInJldmVyYldldCI6MC41NSwiY2hvcnVzRGVwdGgiOjAuMjV9LCJpbnRlcmFjdGl2aXR5Ijp7InNjcm9sbFRhcmdldCI6ImZpbHRlckZyZXEiLCJzY3JvbGxNdWx0aXBsaWVyIjozLjUsImhvdmVyTm90ZVRyaWdnZXIiOnRydWV9fX0="
        defer></script>

La semilla es el widget. Incluye colores, textos y parámetros musicales. No hace falta ningún otro servicio: si el backend de vibedom desapareciera, este botón seguiría funcionando.

Webflow, Framer o WordPress

Pega el snippet en el HTML personalizado del proyecto o en el pie de la página. En WordPress, usa un plugin de «code snippets» o el footer.php del tema hijo. Evita los campos que limpian etiquetas <script>.

Un widget por página es suficiente. No lo pongas en el checkout ni en el panel de administración: suena mejor en la web pública, donde el visitante decide pulsar.

2. Atributos

Atributo Obligatorio Qué hace
src Sí URL del cargador. Usa siempre https://vibedom.dev/widget.js.
data-seed Sí Semilla Sonora en base64, tal como la genera el playground. Si falta o está corrupta, el widget no se muestra y no rompe la página.
data-label No Texto del botón y de su etiqueta accesible. Por defecto es «Escuchar esta web» o «Play this website» según el lang del documento.
defer Recomendado No bloquea el render de la página anfitriona.

Colores y textos

El botón toma backgroundColor, accentColor y textColor de uiTheme dentro de la semilla. Si el acento y el fondo coinciden, usa el color de texto para que el icono siga viéndose. Para cambiar la paleta, regenera la semilla en el playground; no hace falta tocar CSS.

Ejemplo con texto propio
<script src="https://vibedom.dev/widget.js"
        data-seed="…"
        data-label="Ponle sonido a esta página"
        defer></script>

3. Cómo funciona

  1. Al cargar la página, el snippet decodifica la semilla y pinta un botón dentro de un Shadow DOM. No descarga el motor ni Tone.js. El cargador pesa menos de 5 KB (unos 2 KB comprimido).
  2. Al primer clic, carga widget-player.js y Tone.js desde jsDelivr. Ese primer clic es también el gesto que los navegadores exigen para crear el contexto de audio.
  3. Mientras suena, el motor interpreta la semilla en el navegador: pad, drone y arpegio. No hay audio pregrabado ni peticiones a la API.

El botón tiene aria-pressed, foco visible y respeta prefers-reduced-motion. Los estados de carga y error se anuncian en su etiqueta accesible, no con un alert que interrumpa al visitante.

4. CSP y SRI

Si la web anfitriona usa una Content-Security-Policy estricta, añade estos orígenes. El widget necesita jsDelivr para Tone.js, blob: para el reloj y los worklets internos de Tone, y estilos inline para el Shadow DOM:

Content-Security-Policy
script-src 'self' https://vibedom.dev https://cdn.jsdelivr.net blob:;
worker-src blob:;
style-src 'self' 'unsafe-inline';

No pegues esto encima de tu CSP actual. Únelo con la que ya tengas: cada directiva se combina y una CSP duplicada puede desactivar la más permisiva o romper el resto de la web.

Integridad (SRI)

Puedes añadir integrity y crossorigin="anonymous" al cargador. El hash cambia cada vez que se publica una versión nueva de widget.js; si lo fijas, revisa el hash al actualizar. Puedes calcular el actual con:

Terminal
curl -s https://vibedom.dev/widget.js \
  | openssl dgst -sha384 -binary \
  | openssl base64 -A

El SRI protege el cargador; el reproductor y Tone.js se importan en tiempo de ejecución y no admiten integrity. Por eso, además del hash, fija la versión en la URL (ver Versionado).

5. Privacidad y coste

  • No hay cookies, localStorage ni analítica de vibedom.
  • La URL de la página anfitriona no se envía a ningún servidor.
  • El audio se sintetiza en el navegador; no se descarga música ni se sube nada.
  • El primer clic pide Tone.js a jsDelivr, que ve la IP del visitante como cualquier CDN. Si necesitas evitarlo, escríbenos antes de integrarlo en un entorno con requisitos estrictos.
  • Coste por visitante: cero llamadas a la IA. La semilla ya está incrustada en el HTML.

6. Problemas frecuentes

No aparece el botón

Comprueba que data-seed no esté vacío ni cortado al copiar, y que la CSP permita https://vibedom.dev. Si el snippet está dentro de un editor que elimina <script>, muévelo al HTML del tema o a un plugin de código.

El botón aparece, pero no suena

El audio necesita el gesto del clic: no se puede autoplay. En iOS revisa también el interruptor de silencio. Si la CSP bloquea blob:, Tone no puede arrancar su reloj interno.

El primer clic tarda un segundo

Es normal: en ese momento se descargan el reproductor y Tone.js (unos 230 KB comprimidos desde el CDN). El botón muestra el estado de carga mientras tanto.

Quiero el botón en otra esquina o con otro tamaño

La posición y el tamaño forman parte del diseño del widget y no se configuran por atributo. Si necesitas una variante para un cliente, regenera la semilla y pide una adaptación antes de tocar el CSS del Shadow DOM.

¿Puedo poner varios widgets en la misma página?

No. Cada snippet crea su propio botón flotante y dos botones se solapan. Usa uno por página.

7. Versionado

Para evitar que una actualización cambie el widget de un cliente sin avisar, añade la versión a la URL:

URL con versión
https://vibedom.dev/widget.js?v=1.0.0

El parámetro rompe la caché del navegador y del CDN, pero el archivo sigue siendo el publicado. Antes de subir de versión, revisa el changelog. Los cambios de semilla no afectan al widget: cada snippet lleva la suya.

¿Listo para probarlo? Genera una semilla con tu web y copia el snippet final.

Abrir el playground