# Insertar un formulario en tu web

Pega el código de un formulario de captación en tu web, elige cómo y cuándo aparece, mide el origen de las visitas y entiende qué hacen los orígenes permitidos.

Un formulario de captación se pone en cualquier web pegando dos líneas de HTML. El formulario se pinta solo, con los campos y estilos que hayas definido en UTILIA OS, y cada envío llega al CRM: crea un lead o, si la persona ya lo era, se añade a su ficha. Esta página explica el código, los formatos y disparadores, la medición del origen y lo que conviene saber sobre CORS. Cómo diseñar el formulario está en la guía de [Formularios de captación](https://os.utilia.ai/docs/guides/lead-forms/overview).

## El código

```html
<!-- Formulario UTILIA: Formulario de contacto -->
<div data-utilia-form="abc123xyz0" data-api-url="https://os.utilia.ai/api"></div>
<script src="https://os.utilia.ai/api/v1/forms/widget.js" async></script>
```

- `data-utilia-form` lleva el `slug` del formulario.
- `data-api-url` es la dirección de la API. El script la deduce de su propia dirección y solo usa este atributo si no puede; si no la encuentra, muestra un error de configuración en el lugar del formulario.
- `async` hace que el script no retrase la carga de tu página.

Puedes poner varios formularios en la misma página, cada uno en su `<div>` con su `slug`. El script se carga una sola vez.

1. **Publica el formulario**

   Abre el formulario en [Ajustes › CRM › Formularios de captación](https://os.utilia.ai/dashboard/settings/lead-capture) y publícalo. Hasta que no esté publicado no hay código que copiar.
2. **Copia el código**

   En la pestaña «Embeber», pulsa «Copiar» en «Código de embebido».
3. **Pégalo en tu web**

   Pégalo dentro del `<body>`, preferiblemente antes de su cierre. Si el formulario es de tipo integrado en la página, aparecerá exactamente donde pongas el `<div>`.
4. **Haz una prueba**

   Abre la página, envía el formulario con un correo de prueba y comprueba que el lead aparece en el CRM.

## Formatos

| Formato (en el panel) | Valor | Cómo se ve |
| - | - | - |
| Integrado en la página | `INLINE` | Dentro del contenido, en el sitio del `<div>`, siempre visible. |
| Ventana emergente (popup) | `POPUP` | Ventana centrada sobre la página, con el fondo oscurecido. Es el formato por defecto. |
| Panel deslizante lateral | `SIDEBAR` | Panel de 380 píxeles que entra por la derecha o por la izquierda. |
| Barra fija | `BANNER` | Barra arriba o abajo de la pantalla, con un botón que abre el formulario. |

## Disparadores

Deciden cuándo aparece la ventana, el panel o la barra. El formato integrado está siempre visible y no usa disparador.

**Qué disparador admite cada formato**

| Disparador | Ventana emergente | Panel lateral | Barra fija |
| - | - | - | - |
| Botón flotante (button. Un botón redondo fijo en la esquina inferior, con el color principal. Es el disparador por defecto.) | Sí | Sí | No |
| Tras unos segundos (time-delay. Pasados los segundos indicados: 5 por defecto, hasta 300.) | Sí | Sí | Sí |
| Al bajar por la página (scroll. Cuando el visitante ha recorrido el porcentaje indicado: 50 por defecto.) | Sí | Sí | Sí |
| Al intentar irse (exit-intent. Cuando el puntero sale de la ventana del navegador.) | Sí | No | No |
| Inmediato (immediate. Nada más cargar la página.) | No | No | Sí |

«Al intentar irse» depende del ratón: en pantallas de 768 píxeles de ancho o menos no se activa y el formulario no aparece. Si te importan las visitas desde el móvil, elige otro disparador.

## En el móvil

- La ventana emergente ocupa el ancho de la pantalla, con un margen, y como mucho el 90 % del alto.
- El panel lateral ocupa como mucho el 90 % del ancho.
- La barra fija ocupa todo el ancho.
- Con `showOnMobile` desactivado, el formulario no se muestra en pantallas de 768 píxeles de ancho o menos.

## Qué hace el script

**Del código pegado al lead**

Participantes: Navegador del visitante y UTILIA OS.

1. Navegador del visitante → UTILIA OS: `GET /api/v1/forms/widget.js`. Se descarga sin bloquear la página y el navegador lo guarda 24 horas.
2. Navegador del visitante → UTILIA OS: `GET /api/v1/forms/:slug/config`. Pide los campos, el estilo y el disparador.
3. UTILIA OS → Navegador del visitante (respuesta): Configuración pública. El servidor la guarda 5 minutos.
4. Navegador del visitante (por su cuenta): Pinta el formulario según su formato y prepara el disparador.
5. Navegador del visitante → UTILIA OS: `POST /api/v1/forms/:slug/view`. Una sola vez por sesión del navegador.
6. Navegador del visitante (por su cuenta): Al enviar, comprueba los campos obligatorios, el formato del correo y los consentimientos.
7. Navegador del visitante → UTILIA OS: `POST /api/v1/forms/:slug/submit`. Las respuestas, la página de origen y, si los hay, los datos de la campaña.
8. UTILIA OS → Navegador del visitante (respuesta): 201: envío recibido. El formulario muestra el mensaje de confirmación.

_La configuración tarda hasta 5 minutos en reflejar un cambio del formulario; el script, hasta 24 horas._

Si el envío falla, el formulario muestra el error. Los detalles de cada endpoint están en la [API pública de formularios](https://os.utilia.ai/docs/developers/lead-forms/public-api).

Al publicar una versión nueva del script, los navegadores que ya lo tenían siguen usando la anterior hasta 24 horas, porque su dirección no cambia. Si una novedad del formulario no se ve en tu web, espera un día o recarga vaciando la caché antes de pensar que algo falla. Y si el formulario deja de aparecer sin que hayas tocado nada, revisa el plan: sin el CRM o la capacidad de leads, la configuración responde 404.

## Medición del origen de la visita

Con «Guardar el origen del visitante» activado (lo está por defecto), el script lee de la dirección de la página las cinco etiquetas `utm_*` y el identificador de campaña `_ur`, si los trae, y los envía con las respuestas. Así, un lead que llega desde una campaña de correo no aparece como tráfico directo en la analítica de orígenes del CRM.

Para medir el origen, el script no guarda nada en el navegador del visitante: lo lee de la dirección en el momento del envío. Lo único que guarda siempre es una marca en el almacenamiento de sesión del navegador (`sessionStorage`) para contar la vista una sola vez por sesión.

### Recordar el origen entre páginas

Si el visitante llega desde el correo a una página y rellena el formulario en otra, la segunda dirección ya no trae las etiquetas y el origen se pierde. Para ese caso existe «Recordar el origen entre páginas», en la configuración del formulario. Guardar esos datos en el navegador es almacenamiento en el dispositivo del visitante (artículo 22.2 de la LSSI), así que solo ocurre cuando tu web avisa de que esa persona ha dado su consentimiento:

```html
<!-- En el contenedor del formulario -->
<div
  data-utilia-form="abc123xyz0"
  data-api-url="https://os.utilia.ai/api"
  data-utilia-consent="granted"
></div>
```

```javascript
// Desde tu gestor de consentimiento, cuando el visitante acepte
UtiliaForms.setConsent(true);

// Y si lo retira (borra lo que se hubiera guardado)
UtiliaForms.setConsent(false);
```

Solo se recuerdan las cinco etiquetas `utm_*`. El identificador de campaña `_ur` no se guarda nunca en el navegador, haya consentimiento o no.

## Orígenes permitidos y CORS

En la pestaña «Embeber» del formulario, «Orígenes permitidos (CORS)» recoge los dominios desde los que lo vas a usar, por ejemplo `https://tuempresa.com` y `https://www.tuempresa.com`.

CORS es una regla que aplica el navegador, no el servidor de UTILIA OS. Declarar tus dominios sirve para que los navegadores acepten las respuestas de la API cuando el formulario está en tus páginas, pero no impide que alguien envíe tu formulario desde otra página o desde un servidor.

> **Atención: CORS no frena los envíos automatizados**
>
> Los endpoints públicos del formulario no llevan autenticación, por diseño, y CORS solo lo aplica el navegador: una petición desde un servidor o con `curl` llega igual. Lo que frena el abuso es el límite de 10 envíos por minuto por dirección IP, el consentimiento obligatorio y que el formulario esté publicado.

## Ejemplo completo

```html
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tu empresa</title>
</head>
<body>
  <h1>Hablemos</h1>
  <p>Déjanos tus datos y te contamos cómo podemos ayudarte.</p>

  <!-- Formulario UTILIA: Formulario de contacto -->
  <div data-utilia-form="abc123xyz0" data-api-url="https://os.utilia.ai/api"></div>
  <script src="https://os.utilia.ai/api/v1/forms/widget.js" async></script>
</body>
</html>
```

## Siguiente paso

Cuando lleguen los primeros envíos, sigue cuántas vistas se convierten en leads en las [estadísticas del formulario](https://os.utilia.ai/docs/guides/lead-forms/statistics) y trabaja cada lead en el [CRM](https://os.utilia.ai/docs/guides/crm/leads). Si tu web ya tiene su propio formulario y prefieres no cambiarlo, envía sus datos desde tu servidor con la [API de leads](https://os.utilia.ai/docs/developers/lead-forms/leads-api).
