# Instalar FlowConsent en un sitio a medida (HTML)

Instale FlowConsent en un sitio con HTML, PHP, Django, Rails, Laravel, Hugo, Jekyll o Eleventy: pegue el fragmento una vez en el <head> de la plantilla común.

> Canonical: https://www.flowconsent.com/es/doc/install-html
> Last updated: 2026-10-01
En un sitio desarrollado a medida, el fragmento de código de FlowConsent se pega **una sola vez**, al principio del `<head>` de la plantilla que comparten todas las páginas (layout, cabecera incluida, plantilla base), antes que cualquier otro script. La instalación son dos pasos: copiar el fragmento y colocarlo en esa plantilla común. Los dos problemas habituales: una Content-Security-Policy que bloquea el banner y una navegación del lado del cliente que requiere el Modo SPA.

## Antes de empezar

- Una cuenta en [app.flowconsent.com](https://app.flowconsent.com) (el plan Free es gratuito, sin tarjeta de crédito y cubre hasta 25.000 sesiones al mes).
- Un banner creado y desplegado. En el plan Free, el despliegue pasa por su propia cuenta de Cloudflare ([guía de Cloudflare](/es/doc/cloudflare-deployment)); en Pro y Enterprise se hace con un clic.
- Acceso al código fuente del sitio y a su proceso de publicación.

## Paso 1: Copie el fragmento de código

Abra **Builder → Despliegue → Integración** y copie el fragmento de la pestaña **HTML / No-code**. Tiene dos partes, en este orden: el stub de Google Consent Mode v2 (valores `denied` por defecto) y el cargador del banner.

```html title="Al principio del <head>"
<head>
  <script>
  // FlowConsent Loader - COLOCAR ANTES de cualquier otro script en el <head>
  window.dataLayer=window.dataLayer||[];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent','default',{
    'ad_storage':'denied',
    'analytics_storage':'denied',
    'ad_user_data':'denied',
    'ad_personalization':'denied',
    'wait_for_update':500
  });
  gtag('set','url_passthrough',true);
  gtag('set','ads_data_redaction',true);
  </script>
  <!-- FlowConsent CMP -->
  <script src="https://SU-CODIGO-LICENCIA.consent.flowconsent.com/cookie-manager.js?code=SU_CODIGO_LICENCIA"></script>

  <meta charset="utf-8">
  <!-- el resto de etiquetas y scripts van después -->
</head>
```

Cualquier script colocado encima de este fragmento escapa al bloqueo previo, así que debe ir antes de Google Analytics, Meta Pixel, Google Tag Manager y cualquier otro rastreador.

## Paso 2: Péguelo una vez en la plantilla común

Busque el archivo que genera el `<head>` de todas las páginas. Según la tecnología:

- **Sitio HTML estático**: sin plantilla, cada archivo `.html` tiene su propio `<head>`. Pegue el fragmento en cada uno (basta con buscar y reemplazar `<head>`) o use una inclusión del lado del servidor si su alojamiento lo permite.
- **PHP**: la cabecera común, a menudo `header.php`, que cada página incluye con `include` o `require`.
- **Laravel**: el layout de Blade, por ejemplo `resources/views/layouts/app.blade.php`.
- **Django**: la plantilla base (a menudo `templates/base.html`) que las páginas extienden con `{% extends "base.html" %}`.
- **Ruby on Rails**: `app/views/layouts/application.html.erb`.
- **Hugo**: la plantilla base `layouts/baseof.html` (`layouts/_default/baseof.html` en versiones anteriores a Hugo 0.146) o el partial `head.html` al que llama. Con un tema, copie ese archivo en la carpeta `layouts/` del proyecto en lugar de modificar el tema.
- **Jekyll**: el layout `_layouts/default.html`, o `_includes/head.html` con un tema como Minima. Para sobrescribir un archivo del tema, cópielo en la misma ruta dentro de su sitio.
- **Eleventy**: el layout base guardado en `_includes/` (por ejemplo `_includes/base.njk`), que se elige con la clave `layout` del front matter.

El fragmento es HTML estándar: ningún motor de plantillas necesita escaparlo. Si el sitio tiene varios layouts raíz, repita el paso en cada uno. Después, vuelva a generar o a desplegar el sitio.

No pegue los rastreadores (Google Analytics, Meta Pixel…) directamente en la plantilla: declárelos en **Builder → Servicios** y el banner solo los cargará tras el consentimiento. Para Google Tag Manager, consulte la [guía específica](/es/doc/install-google-tag-manager).

## Content-Security-Policy y navegación del lado del cliente

> [!WARNING]
> Si su sitio envía una cabecera `Content-Security-Policy`, el banner queda bloqueado mientras su dominio no figure en ella. Autorice el dominio de su fragmento en `script-src` (carga del script) y en `connect-src` (peticiones del banner a ese mismo dominio): `https://*.consent.flowconsent.com` en Pro y Enterprise, la URL de su Worker de Cloudflare en el plan Free. Como el stub es un script inline, también necesita un `nonce`, un hash `sha256-…` (que hay que recalcular si cambia el fragmento) o `'unsafe-inline'`.

```text title="Ejemplo de cabecera (Pro y Enterprise)"
Content-Security-Policy: script-src 'self' 'nonce-RANDOM' https://*.consent.flowconsent.com; connect-src 'self' https://*.consent.flowconsent.com
```

Añada entonces `nonce="RANDOM"` a las dos etiquetas `<script>` del fragmento, con un valor generado en cada respuesta. Los servicios que el banner carga tras el consentimiento también deben estar autorizados, igual que sin FlowConsent. Si algo se bloquea, la consola del navegador indica la directiva y el dominio rechazados.

> [!NOTE]
> Si su sitio navega sin recargar la página (Turbo en Rails, `wire:navigate` de Livewire, `hx-boost` de htmx, un framework de JavaScript), active el **Modo SPA** en la pestaña **Ajustes** del Builder y vuelva a desplegar el banner: el consentimiento se comprueba de nuevo en cada navegación del lado del cliente. Más detalles en la [guía de Next.js y SPA](/es/doc/nextjs-integration).

## Verificar la instalación

1. Abra el sitio publicado en una ventana privada: el banner aparece.
2. En la pestaña **Red**, no sale ninguna petición a terceros antes de hacer clic en **Aceptar**. La **Consola** no muestra ninguna infracción de CSP.
3. Lance el [asistente de instalación](/es/doc/setup-wizard) (Builder → Integración): revisa la página publicada (cargador presente con el código de licencia correcto, stub de Consent Mode presente y colocado antes de cada etiqueta de Google).
4. Termine con un escaneo de rechazo desde la pestaña **Conformidad** ([verificación de conformidad](/es/doc/compliance-verification)).

## Hágalo desde su agente de IA (MCP)

FlowConsent tiene un servidor MCP oficial, `https://mcp.flowconsent.com`, que funciona con Claude, ChatGPT o cualquier cliente MCP. La conexión se hace por OAuth 2.0 con su cuenta de FlowConsent, sin clave de API. Su agente obtiene el fragmento de código y las instrucciones de colocación (`get_banner_snippet`, `get_setup_instructions`), verifica la instalación con un escaneo real (`verify_consent_compliance`) y puede programar una supervisión recurrente (`monitor_compliance`). La plantilla la modifica usted o su agente de código: el servidor MCP aporta el fragmento, las instrucciones y la verificación.

Ejemplo de petición:

> Deme el fragmento de código de mi banner para mi sitio HTML a medida, dígame dónde colocarlo en mi plantilla y compruebe que está bien instalado en https://misitio.es

Más información: [servidor MCP](/es/doc/mcp-server) y [FlowConsent para agentes de IA](/es/mcp).

## Preguntas frecuentes

### ¿Hay que pegar el fragmento en cada página?

Debe estar presente en cada página, pero solo lo pega una vez si las páginas comparten plantilla. Únicamente un sitio en HTML puro sin plantilla obliga a añadirlo archivo por archivo.

### ¿Puedo colocarlo al final del `<body>`?

No. El stub de Consent Mode debe ejecutarse antes que cualquier rastreador: al final de la página, los scripts situados más arriba ya se habrían ejecutado. Colóquelo al principio del `<head>`.

### El banner no aparece: ¿por dónde empiezo?

Abra la consola del navegador. Un error de CSP indica un dominio que hay que autorizar. Si no, compruebe que el fragmento está en el HTML que se sirve realmente (código fuente de la página), con su código de licencia.

### Mi sitio se genera de forma estática: ¿funciona el banner sin servidor?

Sí. El fragmento se ejecuta en el navegador, así que funciona en cualquier alojamiento de archivos estáticos.
