aidisclose.js es el script integrado en el sitio que lee tu manifiesto ai-disclosure.json y muestra las divulgaciones que exige la ley: un aviso de interacción para chatbots, un aviso de contenido persistente, etiquetas visibles en los medios marcados y metadatos de página legibles por máquina. No tiene dependencias, ocupa unos 8.2 KB comprimidos con gzip y cumple con WCAG 2.1 AA.
Esta página es la referencia completa de configuración y personalización. Para los pasos de instalación plataforma por plataforma (WordPress, Shopify, Webflow, gestores de etiquetas), consulta la guía de instalación. También puedes leer este documento como markdown en bruto.
Descripción general
Una sola etiqueta de script lo gobierna todo. Al cargarse, el snippet obtiene tu manifiesto y luego muestra únicamente lo que el manifiesto declara:
- Aviso de interacción, para un sistema
conversational: un aviso de que la persona visitante está hablando con una IA. - Aviso de contenido, para un sistema
content-generationconscope: siteoscope: page: una pequeña etiqueta persistente. Al pulsarla se abre una breve explicación con el texto del aviso, el nombre de tu entidad editora y el propósito del sistema tomados del manifiesto, y un enlace al archivo del manifiesto; el texto del aviso enlaza a una explicación en lenguaje sencillo en aidisclose.io. La insignia "hecho por personas" abre la misma tarjeta con el nombre de la entidad editora. - Etiquetas por elemento, en cualquier elemento que marques con
data-ai-content: una insignia "IA" visible, más undata-digital-source-typelegible por máquina. - Metadatos de página: un
<link rel="ai-disclosure">y un<meta name="ai-disclosure">que apuntan a tu manifiesto. - Insignia "hecho por personas", cuando el manifiesto define
noAiDeclared.
Todo lo que sigue es opcional. Sin ninguna configuración, el snippet lee tu /.well-known/ai-disclosure.json, se muestra en el idioma de la persona visitante en 28 idiomas, sigue la preferencia de tema claro u oscuro del sistema operativo y se apila por encima de las barras de consentimiento de cookies conocidas, de modo que ambas nunca se solapan.
Instalación
Añade la etiqueta una sola vez, en la plantilla compartida de tu sitio, en la cabecera del tema o en el gestor de etiquetas, y se incluirá en todas las páginas. Puede ir en el <head> o en cualquier punto antes de </body>; se carga de forma diferida, por lo que su ubicación no cambia el comportamiento:
<script src="https://cdn.aidisclose.io/v1/aidisclose.js" defer></script>
Sin atributos, el snippet lee el manifiesto en https://YOURDOMAIN/.well-known/ai-disclosure.json. Si tu plataforma no puede servir un archivo en la raíz del dominio, aloja el manifiesto con AIDisclose y apunta la etiqueta a él mediante la clave:
<script src="https://cdn.aidisclose.io/v1/aidisclose.js" data-aidisclose="YOUR_SITE_KEY" defer></script>
Si no se puede acceder al manifiesto, el snippet registra una advertencia en la consola y no muestra ningún aviso derivado del manifiesto, de modo que un fallo de obtención nunca muestra un aviso adivinado. Los metadatos de página, tus etiquetas [data-ai-content] y un aviso forzado con data-banner="true" siguen mostrándose.
Configuración
Hay tres formas de configurar el snippet. Usa la que mejor se adapte a tu plataforma.
1. Atributos en la etiqueta de script. La vía más sencilla, sin código adicional:
<script src="https://cdn.aidisclose.io/v1/aidisclose.js"
data-theme="light" data-lang="fr" defer></script>
2. Un objeto de configuración global. Define window.AIDiscloseConfig antes de que se ejecute el script. Expone el conjunto completo de opciones, incluidas las opciones de selector que no tienen forma de atributo:
<script>
window.AIDiscloseConfig = {
theme: 'light',
mountSelector: '#ai-disclosure-slot',
triggerSelector: '#chat-launcher',
};
</script>
<script src="https://cdn.aidisclose.io/v1/aidisclose.js" defer></script>
3. Inicialización manual. Añade data-manual para diferir el arranque automático y luego llama tú mismo a AIDisclose.init() cuando tu aplicación esté lista (útil en aplicaciones de una sola página):
<script src="https://cdn.aidisclose.io/v1/aidisclose.js" data-manual defer></script>
<script>
AIDisclose.init({ theme: 'dark', persistentChip: false });
</script>
Si hay más de una fuente presente, window.AIDiscloseConfig prevalece: anula tanto los atributos de la etiqueta de script como cualquier objeto pasado a AIDisclose.init().
Referencia de opciones
La superficie de opciones es estable para la línea 1.x.
| Option | Attribute | Values | Default | Effect |
|---|---|---|---|---|
theme |
data-theme |
light, dark, auto |
auto |
Esquema de color. auto sigue la preferencia del sistema operativo de la persona visitante. |
siteKey |
data-aidisclose |
cadena de texto | ninguno | Carga el manifiesto alojado en AIDisclose para esta clave en lugar del archivo well-known. |
manifestUrl |
data-manifest-url |
URL | /.well-known/ai-disclosure.json |
Lee el manifiesto desde una URL personalizada. |
lang |
data-lang |
código BCP-47 | <html lang> de la página; en su defecto, el idioma de la persona visitante |
Fuerza un idioma de visualización. |
banner |
data-banner |
true, false |
auto | Fuerza el aviso de interacción a mostrarse u ocultarse. Sin definir, solo aparece cuando tu manifiesto declara un sistema conversacional (chatbot). |
persistentChip |
— | true, false |
true |
Muestra u oculta la mini-etiqueta contraída del aviso de interacción (la pequeña píldora a la que se minimiza). |
alwaysShow |
— | true, false |
false |
Muestra el aviso de nuevo en cada visita, ignorando el descarte de la persona visitante (recordado en el localStorage del navegador). |
mountSelector |
— | selector CSS | ninguno | Muestra el aviso en línea dentro de este elemento en lugar de la superposición fija inferior. |
triggerSelector |
— | selector CSS | ninguno | Muestra el aviso de interacción solo después de que la persona visitante pulse este elemento, como un lanzador de chat. Las páginas sin un elemento coincidente no muestran ningún aviso, de modo que un chatbot presente en algunas páginas se divulga solo ahí. Los lanzadores inyectados tras la carga también funcionan. Quien haya descartado antes el aviso sigue viendo la mini-etiqueta. |
adjacentSelector |
— | selector CSS | ninguno | Coloca una etiqueta junto a un elemento que no puedes marcar directamente, como un widget cerrado o un iframe. |
observe |
— | true, false |
true |
Observa el DOM en busca de contenido añadido más tarde y lo etiqueta. Define false en páginas totalmente estáticas. |
beaconUrl |
— | URL | ninguno | Envía una baliza anónima {siteKey, flag} en eventos relevantes. Sin cookies, sin datos personales. |
data-manual no es un valor de opción: su presencia en la etiqueta difiere el arranque automático para que puedas llamar tú mismo a AIDisclose.init().
Tema y apariencia
Define el esquema integrado con theme (light, dark o auto). Para que coincida exactamente con tu marca, sobrescribe las propiedades personalizadas de CSS del snippet en tu propia hoja de estilos. Se definen en .aid-banner, .aid-chip:
| Variable | Controls |
|---|---|
--aid-bg |
Fondo |
--aid-fg |
Texto |
--aid-line |
Borde |
--aid-btn |
Borde del botón de descarte |
--aid-btnfg |
Texto del botón de descarte |
--aid-hov |
Estado hover del botón de descarte |
.aid-banner, .aid-chip {
--aid-bg: #0b1020;
--aid-fg: #e8eaed;
--aid-line: #2a2f36;
}
El snippet no incluye reglas !important y usa selectores de baja especificidad, por lo que tu CSS prevalece. Los enganches de clase son .aid-banner, .aid-chip, .aid-badge, .aid-badge-inline, .aid-wrap, .aid-ai (aviso de contenido) y .aid-hm ("hecho por personas"). Reestiliza el espaciado, el radio y la sombra directamente sobre estos.
De forma predeterminada, el aviso es una superposición fija en la parte inferior de la ventana. Define mountSelector para mostrarlo en línea y de forma estática dentro de un elemento que controles, de modo que quede dentro de tu propio diseño.
Texto personalizado
El aviso y la etiqueta llevan de fábrica texto localizado y preciso en 28 idiomas. Para sobrescribir el texto:
- Por idioma, en el manifiesto. Añade
disclosure.textsa un sistema, indexado por código de idioma. El snippet usa tu texto para el idioma coincidente de la persona visitante:
{
"disclosure": {
"texts": { "en": "Some copy on this page was drafted with AI.", "fr": "Une partie du texte a été rédigée avec de l'IA." }
}
}
- Por elemento. Añade
data-ai-labela un elemento marcado para definir la etiqueta de esa insignia.
Cuando un sistema define editorialResponsibility.humanReview: true y su contenido no está totalmente generado o manipulado por IA, el aviso muestra automáticamente "asistido por IA, revisado por personas" en el idioma de la persona visitante, en lugar de "generado por IA".
Marcado de tu contenido de IA
El snippet solo etiqueta lo que marcas. Añade data-ai-content a cualquier elemento generado por IA:
<img data-ai-content src="/img/generated.webp" alt="…">
<p data-ai-content>AI-drafted summary…</p>
<video data-ai-content src="/clip.mp4"></video>
Cada elemento marcado recibe una insignia "IA" visible y un data-digital-source-type legible por máquina (con valor predeterminado trainedAlgorithmicMedia, un valor compatible con IPTC y schema.org). Añade data-ai-label para un texto de etiqueta personalizado, o define tú mismo data-digital-source-type para ser más específico.
Para IA que no puedes anotar directamente, como un widget de chat de terceros en un iframe cerrado, usa adjacentSelector para colocar una etiqueta a su lado, o triggerSelector para revelar el aviso de interacción cuando el widget se abra.
Un aviso de generación de contenido puede cubrir todo el sitio (disclosure.scope: "site") o páginas concretas (disclosure.scope: "page" con una lista disclosure.pages de patrones de ruta, como /blog/*). Una coincidencia de ámbito de página tiene prioridad sobre una de ámbito de sitio, y un sistema con ámbito de página sin ruta coincidente no muestra nada ahí.
Aplicaciones de una sola página y frameworks
El snippet observa el DOM con un MutationObserver y reevalúa el aviso aplicable en los cambios de ruta, de modo que el contenido y las páginas añadidos tras la carga también se etiquetan. En una SPA:
- Mantén
observeen su valor predeterminado (true) para captar el contenido renderizado en el cliente. - Si condicionas la inicialización a que la aplicación esté lista, añade
data-manualy llama aAIDisclose.init()después de que tu framework se monte. - Los avisos de ámbito de página se actualizan automáticamente al cambiar la ruta; no hace falta ninguna llamada por ruta.
Define observe: false solo en páginas totalmente estáticas donde no se inyecta nada tras la carga.
Política de seguridad de contenido
Si aplicas una política de seguridad de contenido, autoriza el snippet de forma explícita.
Importante
Un script-src 'self' estricto bloquea el snippet de la CDN de forma silenciosa, y las divulgaciones nunca se muestran. Esta es la razón más común por la que un sitio correctamente declarado no alcanza el Nivel 2.
script-src: añadehttps://cdn.aidisclose.io, o aloja tú mismoaidisclose.jsdesde tu propio origen y mantén'self'.style-src: el snippet inyecta sus estilos en línea, por lo que basta con'unsafe-inline'. Si no permites estilos en línea, recurre a cargaraidisclose.cssdesde el directorio del script, así que autoriza tambiénhttps://cdn.aidisclose.ioenstyle-src(o aloja tú mismo ese archivo junto al script).connect-src: la obtención del manifiesto es del mismo origen para el archivo well-known y no necesita nada adicional. Si cargas el manifiesto por clave, autorizahttps://cdn.aidisclose.io.
El manifiesto se obtiene sin credenciales, así que sírvelo públicamente: un endpoint que requiera cookies o autenticación no las recibirá.
Versionado e integridad
La CDN sirve tres canales:
/v1/aidisclose.jssigue la última versión 1.x. Recomendado para la mayoría de los sitios./v1.0.0/aidisclose.jses una versión fija e inmutable que puedes anclar, con Subresource Integrity:
<script src="https://cdn.aidisclose.io/v1.0.0/aidisclose.js"
integrity="sha384-…" crossorigin="anonymous" defer></script>
/latest/aidisclose.jssigue siempre la versión más reciente en todas las versiones mayores.
Para obtener el hash SRI que anclar, compila el snippet: npm run build en packages/snippet lo imprime (el código fuente está abierto en GitHub).
Creación de tu propia interfaz de divulgación
Puedes renderizar tu propia interfaz de divulgación en lugar de la integrada. No hay un único interruptor de apagado: data-banner="false" y persistentChip: false suprimen únicamente el aviso de interacción y su etiqueta, mientras que los avisos de contenido, las insignias por elemento [data-ai-content] y la insignia "hecho por personas" siguen mostrándose a partir de tu manifiesto y tu marcado. Una interfaz totalmente personalizada implica no depender de esas y renderizar la tuya propia.
Nota
El verificador de AIDisclose comprueba el renderizado detectando el marcado del snippet de referencia. Una divulgación construida completamente a mano es válida, pero no se detecta automáticamente, así que el sitio permanece en el Nivel 1 (Declarado) en lugar del Nivel 2 (Mostrado) a menos que tu marcado personalizado reproduzca lo que el verificador busca. Si el Nivel 2 te importa, mantén el renderizado integrado y reestilízalo con CSS.
Accesibilidad
La interfaz renderizada cumple con WCAG 2.1 AA: contornos :focus-visible visibles en los controles interactivos, roles y etiquetas correctos, contraste que se mantiene en claro y oscuro, y animación condicionada a prefers-reduced-motion. El snippet también detecta las barras de consentimiento de cookies conocidas y se apila por encima de ellas para que las divulgaciones nunca queden ocultas tras una CMP. En pantallas muy estrechas, el aviso de interacción se abre como la etiqueta compacta para que nunca cubra el contenido.