¿Cómo podemos ayudarte?

[Beta] Integrar AppsFlyer Web SDK

  • Actualización

De un vistazo: instala el SDK web de AppsFlyer (también conocido como el píxel) en tu sitio web para reportar las visitas y los eventos de los usuarios a AppsFlyer, y configura un ID de usuario de cliente (CUID) persistente para unificar viajes entre plataformas.

Visión general

Web SDK te permite registrar cómo interactúan los visitantes con tu sitio web y envía esta información a AppsFlyer. Es un módulo complementario de 40–60 KB que reporta las visitas y acciones de los usuarios en tu sitio web a la plataforma AppsFlyer.

Integra el SDK manualmente

 Sigue los pasos a continuación para completar la integración de Web SDK, desde la instalación hasta la validación y los controles de privacidad.

  1. Obtén tus claves. Obtén el Web SDK ID (también conocido como Web Dev Key).
  2. Selecciona un snippet de código. Elige el snippet que coincida con tu tipo de integración y requisitos de seguridad.
  3. Implementa Web SDK. Implementa el SDK utilizando un snippet nativo, Google Tag Manager o Adobe Launch Tag Manager.
  4. Asegúrate de que el SDK funcione correctamente. Valida que el SDK envíe solicitudes verificando las llamadas de red en las herramientas para desarrolladores del navegador.
  5. Configura y registra eventos. Define y envía eventos personalizados al cargar la página o mediante la interacción del usuario utilizando JavaScript nativo o Google Tag Manager.
  6. Configura el customer user ID. Configura un CUID persistente para unificar la actividad web con otras plataformas.
  7. Gestiona la privacidad. Controla la activación o desactivación de la medición y configura la seguridad y el filtrado de datos (Content Security Policy y descarte de parámetros de consulta).
  8. Referencia de cookies de Web SDK. Revisa las cookies que Web SDK establece o utiliza, incluyendo su propósito, duración y alcance.

Integra el SDK con un agente de codificación de IA

En lugar de integrar manualmente el SDK web (consulta los pasos a continuación), usa una herramienta de codificación con IA (Cursor, Claude Code, Codex, Copilot) para implementar toda la integración por ti. Copia el prompt, sustituye los dos marcadores de posición y pégalo en tu herramienta de codificación con IA.

Este enfoque agiliza y cubre todos los pasos a continuación, pero aun así debes asegurarte de que el SDK funcione correctamente y revisar tu configuración de privacidad después.

Antes de copiar el prompt, sustituye:

  • <WEB_SDK_ID>: En AppsFlyer, ve a Configuración de la app, selecciona tu aplicación web (el dominio de tu sitio web con el prefijo "website-") y copia el ID del SDK web de Autenticación del SDK.
  • <PRODUCTION_URL>: La URL de tu sitio en producción, usada para la verificación posterior al despliegue.

La herramienta de IA crea un plan de eventos a partir de tu base de código y espera tu aprobación antes de implementarlo. Revisa el plan, confirma que los valores de ingresos y moneda aparezcan solo en los eventos de ingresos reales, y verifica los resultados con los pasos de verificación posterior al despliegue del prompt.

Prompt de implementación con IA
# **AppsFlyer Web SDK - Prompt de implementación con IA**

Copia el prompt de abajo en una herramienta de IA para programar que pueda editar tu proyecto (Cursor, Claude Code, Codex, Copilot). Antes de copiarlo, sustituye dos marcadores de posición:

  - <WEB_SDK_ID> - en AppsFlyer, ve a My Apps, selecciona tu aplicación web (tu dominio con el prefijo website-) y copia el Web SDK ID (también llamado Web Dev Key) desde SDK authentication.
  - <PRODUCTION_URL> - la URL de tu sitio activo, que se usa para la verificación posterior al despliegue.

Implementa el AppsFlyer Web SDK (píxel de atribución web) en este sitio web, incluidos los eventos importantes para mi medición de marketing.

Mi Web SDK ID: <WEB_SDK_ID>

Mi URL de producción: <PRODUCTION_URL>

## Paso 0 - Puerta de configuración

Si falta el Web SDK ID de arriba o sigue siendo un marcador de posición, responde SOLO con una solicitud breve para pedirlo (en AppsFlyer: My Apps > la aplicación con el prefijo "website-" > SDK authentication > Web SDK ID) y detente. No escribas ningún código hasta que se proporcione. Si falta la URL de producción, solicítala en la misma respuesta: es necesaria para la verificación posterior al despliegue.

Trabaja con cambios mínimos: deduce las rutas de archivos a partir del repositorio, cambia solo lo que requiera esta integración y conserva los patrones existentes del proyecto.

## Paso 1 - Analiza primero el sitio

Antes de escribir código, revisa la base de código y crea tú mismo el plan de eventos; no me pidas que enumere los eventos:

1. Identifica el framework (HTML simple, React, Next.js, Vue, etc.) y dónde se controla el elemento <head> del documento.

2. Detecta las acciones de conversión en el código. Busca, en orden de fiabilidad:

   - Llamadas de analítica existentes: gtag()/eventos de GA4, Segment analytics.track(), fbq('track'), dataLayer.push (incluidos los objetos de eCommerce): te indican tanto las acciones como dónde ya están los valores (importe, divisa, ID del pedido).

   - Lógica de comercio: módulos de checkout/carrito, páginas o rutas de confirmación de pedido y de agradecimiento, callbacks de pago correcto.

   - Lógica de autenticación: flujos de registro y login, y dónde pasa a estar disponible el ID interno del usuario en el código del cliente.

   - Formularios y CTA: formularios de leads, inicios de suscripción o prueba, descargas.

   - Productos no comerciales o herramientas: si el sitio no tiene flujos de compra, carrito, checkout, registro o login, no inventes eventos de comercio ni de autenticación. Identifica las acciones reales del producto (p. ej., generar, copiar, exportar, descargar, compartir, seleccionar una plantilla o editar parámetros) y, en su lugar, asígnales nombres de evento personalizados y descriptivos.

3. Asigna cada acción detectada al nombre estándar de AppsFlyer:

   - completed order / «Order Completed» / purchase_success -> af_purchase (con eventRevenue)

   - signup / register / account created -> af_complete_registration

   - login / signin -> af_login

   - add to cart / «Product Added» -> af_add_to_cart (af_price, sin eventRevenue)

   - begin checkout / «Checkout Started» -> af_initiated_checkout (af_price, sin eventRevenue)

   - product or content view -> af_content_view

   - subscription started -> af_subscribe; free trial started -> af_start_trial

   - search -> af_search

   Todo lo que no tenga un equivalente estándar conserva un nombre personalizado descriptivo.

4. Para cada evento, identifica en el código la fuente exacta de: el importe cobrado realmente (para af_purchase), la divisa, el ID del pedido o de la transacción y el ID del usuario. Reutiliza las mismas fuentes de datos que usa la analítica actual.

5. Comprueba si existe una plataforma de gestión del consentimiento (CMP), como OneTrust o Didomi. Marca también cualquier interruptor de consentimiento interno o preferencia de privacidad almacenada por el sitio, y pregúntame cómo debería controlar la medición en lugar de decidirlo por mí.

Nota: la analítica existente sirve solo como información de descubrimiento; implementa los eventos de AppsFlyer como llamadas directas a AF(), no retransmitidos a través de Segment/GA4 con sus nombres.

Después, muéstrame el plan de eventos propuesto en una tabla (nombre del evento de AppsFlyer, activador + archivo, fuente de ingresos/af_price, fuente del ID de deduplicación) y espera mi aprobación antes de implementarlo. Marca cualquier evento en el que no hayas podido localizar la fuente del valor en lugar de hacer suposiciones.

## Paso 2 - Instalar el fragmento del SDK

Añade este fragmento cerca de la parte superior de <head> en todas las páginas, con mi ID del SDK web:

<script>

!function(t,e,n,s,a,c,i,o,p){t.AppsFlyerSdkObject=a,t.AF=t.AF||function(){

(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))},

t.AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1,

o.src="https://websdk.appsflyer.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""),

p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "<WEB_SDK_ID>"}})

</script>

Reglas estrictas:

- Usa el fragmento literalmente. NO lo reescribas como un componente personalizado ni como un módulo contenedor. Los SDK envueltos pueden enviar eventos personalizados mientras que la visita automática (el evento LOAD del SDK) nunca se activa; entonces, el sitio muestra cero visitas y no se puede atribuir nada.

- El SDK debe cargarse exactamente UNA VEZ por carga de página. En React/Next.js, evita los nuevos renderizados y el doble montaje (por ejemplo, cárgalo en la plantilla HTML/document raíz, no dentro de un componente que se vuelve a montar). Varias cargas pueden hacer que el SDK deje de funcionar.

- Si el sitio ya carga el SDK de AppsFlyer mediante un gestor de etiquetas (GTM), NO lo añadas también en el código: un cargador, no dos. Avísame si encuentras una etiqueta de AppsFlyer existente.

- NO implementes manualmente un evento de vista de página o de visita. El SDK registra las visitas automáticamente al cargarse; un evento "page_view" hecho manualmente nunca contará como una visita.

- La clave de configuración es webAppId (no appId).

- Si el sitio aplica una Content Security Policy estricta con nonces, añade el nonce a la etiqueta del fragmento inline Y asegúrate de que la política incluya 'strict-dynamic': el fragmento inyecta el script del SDK dinámicamente y, sin 'strict-dynamic', una política basada solo en nonce lo bloquea.

## Paso 3 - Implementa eventos

Formato de la llamada al evento:

AF('pba', 'event', {

  eventType: 'EVENT',            // siempre la cadena literal 'EVENT'

  eventName: 'af_purchase',

  eventRevenue: 49.99,           // nivel superior: solo en ingresos reales

  eventRevenueCurrency: 'USD',   // nivel superior: código ISO de 3 letras; el valor predeterminado es USD si se omite

  eventValue: {                  // metadatos JSON, máximo 1000 caracteres

    "af_order_id": "TXN-12345",

    "af_customer_event_id": "evt-abc-001"

  }

});

Reglas de los eventos: síguelas exactamente:

1. Usa los nombres de eventos estándar de AppsFlyer para que los reportes y los funnels entre plataformas estén alineados: af_purchase, af_complete_registration, af_login, af_add_to_cart, af_initiated_checkout, af_content_view, af_subscribe. Si existe una aplicación móvil, usa los MISMOS nombres de eventos que el SDK móvil. No añadas nunca sufijos de plataforma como "_web".

   Excepción: líneas de compra distintas. Si el sitio vende claramente niveles o categorías de producto distintos que necesiten desgloses separados en el dashboard (por ejemplo, dos productos de suscripción), propón nombres divididos en el plan de eventos (af_purchase_<tier>) en lugar de un único evento genérico, e indica por qué. La segmentación solo mediante eventValue no aparece en las vistas estándar del dashboard. No envíes NUNCA a la vez un evento a nivel de nivel y un evento genérico para la misma compra: eso duplica los datos.

2. Los ingresos van SOLO en el campo eventRevenue de nivel superior, y SOLO en eventos en los que el dinero se haya movido realmente (compra completada, suscripción completada, reserva confirmada). Los valores dentro de eventValue (af_revenue, revenue, price, amount, total) NUNCA se contabilizan como ingresos; poner los ingresos ahí es el error de implementación n.º 1 y da como resultado 0 $ de ingresos en cada compra.

3. Envía siempre eventRevenueCurrency junto con eventRevenue cuando la moneda no sea USD; de lo contrario, todos los importes se registran en USD.

4. Envía el importe real de una sola transacción como un número simple: sin símbolos de moneda, sin céntimos como unidades, sin duplicar el total del carrito más el artículo, sin valor del ciclo de vida.

5. Para los valores monetarios que NO son ingresos realizados (valor de añadir al carrito, valor de inicio de checkout, precio consultado), NO configures eventRevenue. Pon el importe en "af_price" y la moneda en "af_currency" dentro de eventValue. Enviar eventRevenue tanto en af_initiated_checkout como en af_purchase hace que los ingresos se contabilicen dos veces.

6. En las compras, incluye "af_order_id" (el ID de la transacción) dentro de eventValue. Si el código no tiene un ID real de transacción en ese momento, indícalo en el plan de evento en lugar de sustituirlo por un marcador de posición.

7. Incluye un "af_customer_event_id" único dentro de eventValue en cada evento de conversión. El mismo nombre de evento nunca debe activarse dos veces con el mismo ID; genéralo para cada acción y evita que los nuevos renderizados de la SPA disparen el controlador dos veces. Esto también deduplica frente a cualquier flujo del lado del servidor (S2S) que envíe las mismas conversiones.

8. Un evento por acción del usuario. No emitas dos nombres para la misma acción y no retransmitas la misma acción a través de AppsFlyer y de una capa de reenvío con nombres diferentes.

9. Para carritos con varios artículos, añade una matriz "af_order_info" dentro de eventValue: un objeto por artículo con estas claves: sku, ingresos (precio por unidad), qty, content_name, content_type, content_category, marca. En una compra, eventRevenue en el nivel superior sigue conteniendo el total del pedido.

10. Los eventos deben activarse después de que el fragmento del SDK se haya cargado en la página. En las conversiones que terminan en una página de confirmación o de agradecimiento, activa el evento cuando se cargue esa página; en las acciones dentro de la página (clics en botones en una SPA), actívalo desde el controlador de la acción.

11. Payloads mínimos: omite los campos irrelevantes:

    - NO incluyas eventRevenue ni eventRevenueCurrency, a menos que realmente haya habido movimiento de dinero en ese evento. No envíes nunca eventRevenue: 0 ni una moneda predeterminada «por si acaso».

    - NO incluyas eventCategory, eventLabel ni ningún campo de estilo GA/Segment. No forman parte de la API de eventos del SDK web de AppsFlyer.

    - Dentro de eventValue, omite las claves cuyos valores sean una cadena vacía, null, undefined o false (a menos que false en sí mismo tenga significado para esa propiedad).

    - Si un parámetro no es relevante para un evento concreto, no lo incluyas en el payload en absoluto. Es mejor usar un objeto mínimo solo con los campos que correspondan.

    - Que las columnas de ingresos o moneda aparezcan vacías en los reportes de AppsFlyer no significa que los clientes deban enviar ceros o valores predeterminados; deja esos campos sin incluir.

## Paso 4: establecer el ID de usuario del cliente (CUID)

Inmediatamente después de que un usuario inicie sesión o se registre (y en las cargas de página en las que el usuario ya esté autenticado), llama a:

AF('pba', 'setCustomerUserId', '<el ID interno del usuario, como string>');

Reglas:

- Usa el MISMO identificador que las aplicaciones móviles pasan a setCustomerUserId, si existen aplicaciones móviles. Esto es lo que une el viaje de un usuario entre web y móvil.

- Usa un ID interno opaco. Nunca una dirección de correo electrónico, un número de teléfono ni otros datos personales identificables.

- Llámalo lo antes posible; los eventos activados antes no llevarán el CUID.

- setCustomerUserId por sí solo no crea un evento que se pueda reportar. Activa también af_complete_registration al registrarse y af_login al iniciar sesión, después de establecer el CUID, para que esos eventos lo incluyan.

## Paso 5: consentimiento (solo si existe una CMP)

Si el sitio tiene una plataforma de gestión del consentimiento:

- Inicializa el SDK con la medición desactivada: {pba: {webAppId: "<WEB_SDK_ID>", measurementStatus: false}}

- Cuando se conceda el consentimiento: window.AF_SDK.PLUGINS.PBA.enableMeasurement()

- Cuando se revoque el consentimiento: window.AF_SDK.PLUGINS.PBA.disableMeasurement()

Notas:

- Estos métodos del plugin solo existen una vez que el script del SDK haya terminado de cargarse, a diferencia de AF(), que es un stub de encolado disponible de inmediato. Ten en cuenta ese orden.

- Si la medición empieza desactivada, no se registra ninguna visita hasta que se conceda el consentimiento. Deja clara esa contrapartida antes de implementarlo.

Si no hay CMP, usa el snippet estándar (la medición está activada de forma predeterminada).

## Paso 6: verificar

### 6a. Verificación local (durante la implementación)

Ejecuta el proyecto, controla un navegador (Playwright/Puppeteer, o una herramienta de navegador si tienes una) y captura TANTO el payload de la solicitud COMO el estado de la respuesta HTTP de cada llamada a los dominios de AppsFlyer. Comprueba lo siguiente:

- La solicitud del cargador del SDK devuelve 200 y se activa exactamente una vez por cada carga de página (navega entre páginas y vuelve a renderizar componentes para demostrar que no hay doble carga).

- Se activa una solicitud al cargar la página con eventType "LOAD" y un afWebUserId completado, y su respuesta es 2xx; esta es la visita. Sin ella, nada se atribuirá.

- Cada conversión implementada genera exactamente una solicitud de evento, todas con respuesta 2xx, con eventRevenue y eventRevenueCurrency en el nivel superior en las compras, y con af_customer_event_id presente y único.

- Después de un login simulado, las solicitudes posteriores incluyen el ID de usuario del cliente.

Una solicitud capturada NO es una prueba de éxito. Un evento cuya respuesta sea 4xx fue rechazado y nunca aparecerá en los reportes. Indica el código de estado de cada evento que actives y nunca describas un evento como verificado sin él.

Si no puedes ejecutar un navegador, verifica de forma estática: el snippet tiene un único punto de inserción que no puede montarse dos veces; cada controlador de eventos se activa exactamente una vez por acción; los ingresos y la moneda son campos de nivel superior; se puede acceder a setCustomerUserId en todas las rutas de entrada autenticadas. Indica claramente que no se pudo observar ningún estado de respuesta.

### 6b. Verificación tras el despliegue en el dominio real (obligatoria)

Las ejecuciones locales prueban la ruta del código, no la página de producción. Los pipelines de compilación y los procesadores de recursos pueden eliminar, aplazar o reubicar scripts en línea, así que no basta con comprobar el archivo fuente. Después del despliegue:\n\n- Obtén la URL de producción y confirma que el fragmento esté presente en el HTML SERVIDO.

- Carga la página de producción en un navegador y repite en ella cada comprobación de 6a.

- Confirma que el parámetro de consulta af_id de las solicitudes salientes lleve exactamente el ID del SDK web; un ID incorrecto o truncado significa que los eventos se envían con un ID que no existe en mi cuenta y no llegarán a ninguna parte sin mostrar ningún error.

- Usa un ID de usuario de cliente de QA dedicado (por ejemplo, qa_<yyyymmdd>_01) para que la ejecución pueda aislarse más adelante en raw data.

Si todavía no he desplegado, dime que 6b sigue pendiente y dame los comandos exactos y las comprobaciones que debo ejecutar cuando lo haga.

### 6c. Registro de QA\n\nGenera una tabla de la ejecución de verificación para que luego se puedan cotejar las filas en raw data de AppsFlyer, con una línea por evento: marca temporal UTC, nombre del evento, CUID, af_order_id, af_customer_event_id, estado HTTP. Indica la hora de inicio y de fin en UTC de toda la ejecución, y la hora UTC del despliegue si la conoces.

## Paso 7 - Volver a consultar los datos\n\nIncluye en el reporte una guía explícita para confirmar los eventos en AppsFlyer, porque las visitas y las conversiones son tipos de registro distintos y es fácil confundirlos:\n\n- Las visitas se registran automáticamente y aparecen en los datos a nivel de evento como filas SESSION con el nombre del evento VACÍO y ingresos cero; así es el esquema, no es un error. Las primeras visitas y las revisitas aparecen en los datos a nivel de conversión (FIRST_VISIT / REVISIT), no como eventos con nombre. Una exportación con alcance de sesión nunca puede contener eventos in-app, por muy correcta que sea la implementación.

- Las conversiones implementadas aparecen como filas independientes con el nombre del evento informado (af_purchase, af_login, etc.), y con ingresos solo en las filas de compra.

- Los datos extraídos para una ventana temporal ANTERIOR al despliegue no pueden contener los nuevos eventos. Dame la hora UTC del despliegue y dime que consulte solo después de ella. Señala que los campos de hora de atribución pueden ser mucho más antiguos que la hora del evento y referirse a una visita anterior, no a esta ejecución.

- Indica la latencia de reporte prevista y avísame de que no interprete un reporte vacío dentro de esa ventana como un fallo.

- Dime el filtro exacto que debo usar para encontrar la ejecución de QA de 6c (ventana temporal más CUID de QA) y cómo es un resultado correcto.

- Si los eventos devuelven 2xx pero siguen sin aparecer después de la ventana de latencia, indica claramente que se trata de un problema del lado de la cuenta (evento no habilitado para la app web, alcance de reportar o acceso a los datos), no de un defecto del código, y enumera qué debo comprobar en la interfaz de AppsFlyer.

## Resultado\n\nCuando termines, dame lo siguiente:\n\n- Una tabla de todos los eventos implementados: nombre, ubicación del activador (archivo), gestión de ingresos, ID de deduplicación.

- Dónde se instaló el fragmento y cómo se garantiza una sola carga.

- Dónde se llama a setCustomerUserId.

- La tabla del registro de QA de 6c y una separación clara entre lo que verificaste tú mismo (con estados de respuesta) y lo que queda como lista de comprobación manual de QA para mí (página que abrir, acción que realizar, solicitud y estado que esperar).

- La guía del paso 7 para volver a consultar los datos.

- Cualquier cosa que no hayas podido implementar o que necesites de mí (p. ej., dónde está el ID de usuario, qué campo del importe de compra es el total final cobrado, cualquier fuente de valor que te hayas negado a suponer).

No implementes nada que vaya más allá de la integración del SDK web de AppsFlyer descrita aquí.

1. Obtén tus claves

Obtén el Web SDK ID (también conocido como Web Dev Key):

  1. En AppsFlyer, desde el menú superior, abre Mis apps.
  2. Selecciona tu web app (el dominio de tu sitio web con el prefijo "website-").
  3. Copia el Web SDK ID requerido.

Obtén la clave de Smart Banner (si es necesario):

  1. En AppsFlyer, desde el menú lateral, abre Engage > Web to App > Smart Banners.
  2. Copia la Smart Banner Key requerida.

2. Selecciona un snippet de código

Elige el snippet que coincida con tu tipo de integración y requisitos de seguridad. Hay dos opciones disponibles:

  • Standard Web SDK: La integración estándar.
  • Advanced SDK Verification: Una integración avanzada que agrega protección de la cadena de suministro para Web SDK. Usa esto para agregar una capa adicional de seguridad contra el compromiso de CDN, el DNS hijacking y los ataques de intermediarios.

Si estás haciendo la transición del Standard Web SDK al Advanced SDK Verification, reemplaza tu fragmento existente con el nuevo. No agregues el fragmento nuevo además del existente.

Standard Web SDK

Usa este fragmento para implementar la integración estándar del SDK web. Pégalo cerca de la parte superior de la etiqueta en todas las páginas donde quieras cargar el SDK.

Sin Smart Banners
<html>
<head>
    <script>
!function(t,e,n,s,a,c,i,o,p){t.AppsFlyerSdkObject=a,t.AF=t.AF||function(){
(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))},
t. AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1,
o.src="https://websdk.appsflyersdk.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""),
p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "WEB_DEV_KEY"}})
    </script>
    <script>
        window.onload = function () {
            var userEmail = localStorage.getItem('user_email');
            fetch('users/' + userEmail).then(function (res) {
                res.text().then(function (id) {
                    console.log(id);
                    AF('pba', 'setCustomerUserId', id);
                });
            });
        }
    </script>
</head>
<body>
    <h1>Thank You for Signing Up!</h1>
</body>
</html>
Con Smart Banners
<html>
<head>
    <script>
!function(t,e,n,s,a,c,i,o,p){t.AppsFlyerSdkObject=a,t.AF=t.AF||function(){
(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))},
t. AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1,
o.src="https://websdk.appsflyersdk.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""),
p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "WEB_DEV_KEY"}})
    </script>
    <script>
        function storeUserEmail() {
            var userEmail = document.getElementById('email').value;
            localStorage.setItem('user_email', userEmail);
        }
    </script>
</head>
<body>
    <h1>Sign Up</h1>
    <form onsubmit="storeUserEmail()" action="/signup" method="post">
        <div><label>Name</label><input type="text" name="name" id="name"></div>
        <br/>
        <div><label>Email</label><input type="email" name="email" id="email"></div>
        <br/>
        <input type="submit" id="submit">
    </form>
</body>
</html>

Advanced SDK Verification

Advanced SDK Verification agrega protección a la cadena de suministro para el SDK web. Garantiza que el código que se ejecuta en los navegadores de tus usuarios sea exactamente el que publicó AppsFlyer. El código fuente del SDK en sí es idéntico a la integración estándar; solo difieren los mecanismos de entrega y verificación.

Advanced SDK Verification:

  • Agrega una capa adicional de seguridad contra compromisos de CDN, DNS hijacking y ataques de intermediarios.
  • Agrega aproximadamente 250 ms al tiempo de carga del SDK.

Advanced SDK Verification es opcional. La integración estándar sigue siendo totalmente compatible y es el estándar del mercado para los píxeles de análisis de terceros. Advanced SDK Verification proporciona una capa adicional de protección más allá de ese estándar.

Si tu sitio web aplica una Política de Seguridad de Contenido (CSP) mediante una nonce, consulta Política de Seguridad de Contenido (CSP) en la sección “Gestionar privacidad” para ver la variante extendida de este fragmento.

Sin Smart Banners
<script>
  // Queue — buffers AF() calls until the SDK is ready
  window. AppsFlyerSdkObject = "AF";
  window. AF = window. AF || function() {
    (window.AF.q = window. AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
  };
  window. AF.id = window. AF.id || { pba: { webAppId: "WEB_DEV_KEY" } };
  window. AF.plugins = {};

  // Manifest loader config
  window. AF_LOADER_CONFIG = {
    baseUrl: "https://websdk.appsflyersdk.com",
    plugins: ["pba"]
  };

  // Inject manifest loader
  var loaderScript = document.createElement("script");
  loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
  loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
  loaderScript.crossOrigin = "anonymous";
  loaderScript.async = true;
  document.head.appendChild(loaderScript);
</script>
Con Smart Banners
<script>
  // Queue — buffers AF() calls until the SDK is ready
  window. AppsFlyerSdkObject = "AF";
  window. AF = window. AF || function() {
    (window.AF.q = window. AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
  };
  window. AF.id = window. AF.id || { pba: { webAppId: "WEB_DEV_KEY" }, banners: { key: "YOUR_BANNER_KEY" } };
  window. AF.plugins = {};

  // Manifest loader config
  window. AF_LOADER_CONFIG = {
    baseUrl: "https://websdk.appsflyersdk.com",
    plugins: ["banners", "pba"]
  };

  // Inject manifest loader
  var loaderScript = document.createElement("script");
  loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
  loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
  loaderScript.crossOrigin = "anonymous";
  loaderScript.async = true;
  document.head.appendChild(loaderScript);
</script>

3. Implementar el snippet

Implementa el snippet que seleccionaste en el Paso 2 utilizando uno de los siguientes métodos. Asegúrate de que el SDK se cargue una sola vez por carga de página.

Opción A: Agregar directamente a tu sitio web

Repite esto en todas las páginas:

  1. En el snippet del Paso 2, reemplaza WEB_DEV_KEY por tu Web SDK ID (y YOUR_BANNER_KEY si corresponde).
  2. Pega el snippet cerca de la parte superior de la etiqueta del sitio web.
Opción B: Implementar mediante Google Tag Manager (GTM)

Asegúrate de que el SDK se cargue una sola vez por carga de página y configúralo para que se cargue tan pronto como la página se cargue utilizando la priorización de GTM.

  1. Abre Google Tag Manager.
  2. Crea una nueva etiqueta para AppsFlyer Web SDK.
  3. Selecciona el tipo de etiqueta HTML personalizado.
  4. Asigna un nombre descriptivo a la etiqueta.
  5. Pega el snippet del Paso 2 en Configuración de la etiqueta.
  6. Haz clic en Guardar.
  7. Agrega un activador:
    • Para todas las páginas:
      1. Haz clic en Agregar activador.
      2. Selecciona Todas las páginas.
      3. Haz clic en Guardar.
      4. Ingresa un nombre para la etiqueta y luego haz clic en Guardar.
    • Para páginas específicas:
      1. Haz clic en Guardar etiqueta.
      2. En la ventana principal de GTM, selecciona Activadores. Haz clic en Nuevo.
      3. Haz clic en el ícono de lápiz.
      4. Selecciona el tipo de activador Vista de página.
      5. Selecciona Algunas vistas de página.
      6. Configura las condiciones de página y activación según sea necesario.
      7. Haz clic en Guardar.
      8. Asocia el activador a la etiqueta de AppsFlyer Web SDK:
        1. En la ventana principal de GTM, selecciona Etiquetas.
        2. Selecciona la etiqueta que creaste anteriormente.
        3. En el panel de activación, haz clic en el ícono de lápiz.
        4. Selecciona el activador de vista de página que creaste anteriormente.
        5. Haz clic en Guardar.

Las plantillas personalizadas de GTM no son compatibles con Advanced SDK Verification, porque su entorno aislado no permite configurar el atributo integrity necesario para la verificación. Utiliza en su lugar el tipo de etiqueta HTML personalizado.

Opción C: Implementar mediante Adobe Launch Tag Manager

Crear una propiedad en Adobe Experience Cloud

  1. Abre Adobe Experience Cloud > Lanzar.
  2. En Adobe Experience Cloud Launch, haz clic en Ir al lanzamiento.
  3. Haz clic en Nueva propiedad.
  4. Asigna un nombre a la propiedad.
  5. En Plataforma, selecciona Web.
  6. Ingresa el dominio de tu sitio web.
  7. Haz clic en Guardar.

Agregar el snippet a la propiedad de Adobe Launch

  1. En la página Mi propiedad web, selecciona la pestaña Reglas.
  2. Asigna un nombre a la regla. Recomendación: Cargar Web SDK.
  3. En la sección SI, dentro de Eventos, haz clic en Agregar.
    • En Tipo de evento, selecciona Core – DOM Ready.
    • Haz clic en Conservar cambios.
  4. En la sección ENTONCES, dentro de Acciones, haz clic en Agregar.
    • En Tipo de acción, selecciona Código personalizado.
    • Selecciona JavaScript > Abrir editor y pega el snippet del Paso 2 (sin líneas contenedoras).
    • Haz clic en Conservar cambios para cerrar el editor de código.
  5. Haz clic en Guardar.

Agregar la etiqueta de Adobe Launch al sitio web

  1. En la página Mi propiedad web, selecciona la pestaña Entornos.
  2. Busca la fila correspondiente al entorno que deseas publicar (desarrollo o producción).
  3. En la columna Instalar, haz clic en el ícono de cuadro de la fila correspondiente.
  4. En el cuadro de diálogo Instrucciones de instalación web, copia el snippet de código y cierra el cuadro de diálogo.
  5. Pega el snippet de código en la sección head del sitio web.

Publicar el entorno de Adobe Launch

  1. En la página Mi propiedad web, ve a la pestaña Publicación.
  2. En la sección Desarrollo, haz clic en Agregar nueva biblioteca.
    • Asigna un nombre a la biblioteca y selecciona un entorno.
    • En CAMBIOS DE RECURSOS, haz clic en Agregar un recurso.
    • Haz clic en Reglas > Cargar Web SDK > Última versión > Seleccionar y crear una nueva revisión.
    • Haz clic en Guardar.
  3. En la sección Desarrollo:
    • Junto a la biblioteca recién creada, haz clic en el menú de acciones (3 puntos) > selecciona Compilar para desarrollo.
    • Haz clic nuevamente en el menú de acciones > selecciona Enviar para aprobación.
  4. En la sección Enviado:
    • Haz clic en el menú de acciones > selecciona Compilar para staging.
    • Haz clic nuevamente en el menú de acciones > selecciona Aprobar para publicación.
  5. En la sección Aprobado:
    • Haz clic en el menú de acciones > selecciona Compilar y publicar en producción.

4. Asegúrate de que el SDK funcione correctamente

Después de la instalación, verifica que el SDK envíe solicitudes revisando las solicitudes de red en las herramientas para desarrolladores de tu navegador.

Captura de pantalla de DevTools

Para asegurarte de que el SDK funcione correctamente, sigue estos pasos:

  1. Abre el sitio web.
  2. Abre las herramientas para desarrolladores del navegador.
  3. Ve a la pestaña (A) Red.
  4. Actualiza la página.
  5. Filtra por (B) appsflyer. Pueden aparecer dos solicitudes:
    • Cargador del SDK — La URL de la solicitud comienza con https://websdk.appsflyersdk.com. Esto confirma que el script del SDK se cargó correctamente.
    • Datos de eventos — La URL de la solicitud comienza con https://wa.appsflyer.com/events. Esto confirma que el SDK está enviando datos de eventos a AppsFlyer.
  6. Selecciona el mensaje (C) events (la llamada wa.appsflyer.com).
  7. En Headers, (D) asegúrate de que:
    • La URL de la solicitud comienza con https://wa.appsflyer.com/events?site-id=.
    • Parámetro de consulta site_id = WEB_DEV_KEY.
    • El código de estado es 200.
  8. Verifica que site_id coincida con WEB_DEV_KEY en AppsFlyer > menú superior > Mis apps.
  9. Verifica que el SDK se cargue una sola vez. La carga múltiple del SDK puede provocar que deje de funcionar.

Para confirmar en tiempo real y de forma visual la instalación del SDK web y validar que tus eventos se activan correctamente, usa la página de prueba del SDK web.

5. Configurar y registrar eventos

Después de inicializar Web SDK, puedes pasar de medir visitas básicas a capturar acciones específicas de los usuarios. Esta sección te guía para definir y registrar eventos personalizados, como compras o registros, utilizando JavaScript nativo o Google Tag Manager.

Configurar eventos

Los eventos son los componentes fundamentales de la medición web y representan acciones específicas de los usuarios que tienen valor para tu negocio. Para registrar estas interacciones, debes definir la lógica y los parámetros de cada evento, asegurándote de que los parámetros correctos, como ingresos y metadatos personalizados, se envíen a la plataforma de AppsFlyer.

Evento de ejemplo (evento de compra con ingresos asociados)

AF('pba', 'event', {eventType: 'EVENT', eventName: 'purchase', eventRevenue: 12, eventValue: {"key1": 123, "key2": "name", "af_customer_event_id": "evt-abc-001"}});
Tabla de parámetros de eventos de Web SDK
Nombre del parámetro Obligatorio Description
eventType Tipo de evento. Formato: cadena. Completa siempre este parámetro con EVENT. Ejemplo: eventType: "EVENT"
eventName Nombre del evento. Formato: cadena. Ejemplo: Compra, suscripción
eventRevenue No Ingresos asignados a un evento de conversión. Formato: Float
eventRevenueCurrency No Moneda de ingresos. Código de divisa ISO 4217 de 3 caracteres. Predeterminado: USD. Formato: Secuencia
valor del evento No Asignación de parámetros del evento que describen el evento. Utiliza este parámetro para enviar eventos enriquecidos, como SKU de productos y precios de artículos. Formato: JSON. Ejemplo: {"sku": "ABC123", "color": "blue", "unit_price": 3.99, "currency": "USD"} Limitación: 3000 caracteres (se trunca si se supera).
Registrar eventos al cargar la página

Este es el enfoque estándar para las conversiones que terminan con una redirección, como una página de Gracias o de confirmación.

Puedes implementar este activador añadiendo un método de carga de la ventana a tu JavaScript nativo o configurando un activador de vista de página en Google Tag Manager.

Los siguientes ejemplos de código son solo para fines ilustrativos. No utilices este código tal cual; adáptalo a la estructura específica de tu sitio.

Ejemplo: Registrar evento mediante AF Web SDK

Este enfoque es ideal para registrar conversiones que ocurren mediante redirecciones, como una página de agradecimiento para una suscripción a un boletín.

Caso de uso: Un usuario completa el registro a un boletín y es redirigido a una página de confirmación. Deseas registrar el evento de suscripción tan pronto como esa página sea visible.

Ejemplo de carga de página nativa:

window.onload = function(){
  AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category': 'holiday_promotion'}, eventName: 'subscription'});
}

Cómo funciona:

  1. La página carga el contenido necesario.
  2. Una vez que la ventana se ha cargado completamente (window.onload), el script llama automáticamente al método AF().
  3. El evento subscription, junto con sus metadatos asociados (categoría y etiqueta), se envía directamente a AppsFlyer.
Ejemplo: Registrar evento mediante GTM

Este enfoque se utiliza para registrar conversiones exitosas, como una suscripción a un boletín, activando una etiqueta cuando se carga una página de "Gracias".

1. Configurar una página de Gracias

La siguiente estructura HTML carga GTM, que a su vez carga Web SDK. También muestra cómo los datos pueden ponerse a disposición de GTM mediante funciones o localStorage.

<html>\n<head>\n    <script>\n        // Google Tag Manager loads the Web SDK\n        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n        })(window,document,'script','dataLayer','GTM-XXXX');\n    </script>\n    <script>\n        function getResponseFromServer() {\n            return JSON.stringify({ action: 'subscribe', category: 'site actions', label: userEmail })\n        }\n        localStorage.setItem('data', JSON.stringify({ action: 'subscribe', category: 'site actions', label: 'user@email.com' }));\n    </script>\n</head>\n<body>\n    <h1>Gracias por registrarte en nuestro boletín</h1>\n</body>\n</html>

2. Configurar la etiqueta de GTM

  1. Crea una nueva etiqueta en GTM y selecciona el tipo de etiqueta HTML personalizado.
  2. Asigna un nombre distintivo (por ejemplo, "AF Subscription Event").
  3. Pega el siguiente script en el área de texto HTML:

    AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'subscription'});
  4. Expande Configuración avanzada > Secuenciación de etiquetas. Asegúrate de que esté configurada para activarse después de la etiqueta principal de inicialización de Web SDK.
  5. Configura un activador para que esta etiqueta se active en la Vista de página de tu página de "Gracias".
Registrar eventos mediante la interacción del usuario

Utiliza esto para medir acciones sin recargar la página (clics en botones, descargas, agregar al carrito).

Estas interacciones generalmente se gestionan vinculando un listener de clics a un elemento HTML nativo o utilizando variables de Google Tag Manager para identificar y medir IDs de elementos o selectores CSS específicos.

Los siguientes ejemplos de código son solo para fines ilustrativos. No utilices este código tal cual; adáptalo a la estructura específica de tu sitio.

Ejemplo: Registrar evento mediante AF Web SDK

Utiliza este método para medir acciones específicas que los usuarios realizan en una página, como hacer clic en un botón de checkout o descarga.

Caso de uso: Gestionas un sitio de ecommerce y deseas capturar un evento checkout en el momento en que un usuario hace clic en el botón Checkout de su carrito de compras.

Ejemplo de interacción nativa del usuario:

<html>
<head>
    <script>
        window.onload = function () {
            document.getElementById('checkout').addEventListener('click', function () {
                AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'checkout'});
            });
        }
    </script>
</head>
<body>
    <h1>Carrito de la compra</h1>
    <button id='checkout'>Checkout</button>
</body>
</html>

Cómo funciona:

  1. Cuando la página se carga, el script adjunta un listener de evento click al elemento con el ID checkout.
  2. Cuando el usuario hace clic en el botón, se ejecuta la función callback.
  3. La función puede obtener datos relevantes (por ejemplo, desde localStorage) y pasarlos al método AF().
  4. Luego, el SDK transmite el evento checkout a la plataforma AppsFlyer.
Ejemplo: Registrar evento mediante GTM

Este método captura acciones específicas, como hacer clic en un botón Checkout, utilizando variables y activadores integrados de GTM.

1. Configurar una página de checkout

<html>
<head>
    <script>
        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','GTM-XXXX');
    </script>
</head>
<body>
    <h1>Carrito de la compra</h1>
    <button id='checkout'>Checkout</button>
</body>
</html>

2. Configurar variables y activadores de GTM

  1. En GTM, haz clic en Variables > Configurar y habilita Elemento de clic en la lista de variables integradas.
  2. Crea una nueva variable definida por el usuario (Tipo: Todos los elementos).
  3. Crea un nuevo Activador:
    • Tipo de activador: Clic - Todos los elementos.
    • Este activador se ejecuta en: Algunos clics.
    • Condición: Elemento de clic coincide con el selector CSS #checkout.

3. Crear la etiqueta de interacción

  1. Crea una nueva etiqueta HTML personalizado para la acción de checkout.
  2. Pega el script de interacción:

    <script>
      AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'checkout'});
    </script>
  3. Asigna el activador "Checkout Click" que creaste en el paso anterior.
Mejores prácticas para la implementación de eventos

Para garantizar la precisión de los datos y una transmisión exitosa, ten en cuenta los siguientes requisitos técnicos:

  • Orden de carga: Asegúrate de que la etiqueta de funciones de Web SDK esté completamente cargada en el ámbito de la página antes de realizar cualquier llamada de evento.
  • Formato de datos: No incluyas caracteres especiales en los valores de los eventos. Por ejemplo, utiliza valores numéricos para los ingresos en lugar de incluir símbolos de moneda (usa 10.50 en lugar de $10.50).
  • Límites de cadena: Mantén concisas las cadenas de eventValue; los valores de más de 3000 caracteres se truncarán.
  • Deduplicación de eventos: Recomendamos enviar af_customer_event_id en eventValue, con un valor único por evento. Esto es especialmente importante cuando envías el mismo evento tanto a través del SDK web como de la API de servidor a servidor (S2S). AppsFlyer reenvía este valor a la ad network, que lo usa para deduplicar el evento del servidor que recibe de AppsFlyer frente al mismo evento que recibió de su propio píxel.
  • Ubicación de los ingresos: Rellena eventRevenue solo en eventos en los que realmente hubo un movimiento de dinero, como una compra o una suscripción confirmada. En los eventos que tienen un valor monetario pero no son ingresos reales (por ejemplo, añadir al carrito, inicio de checkout o visualización de contenido), usa af_price y af_currency en eventValue en su lugar. Enviar eventRevenue tanto en el checkout como en la compra duplica los ingresos en cada reporte.
  • Nomenclatura de eventos: No añadas sufijos de plataforma como _web a los nombres de evento. La plataforma ya es una dimensión en el dashboard y en los raw data. Usa los mismos nombres de evento que en tu aplicación móvil para mantener unificados los reportes multiplataforma.

6. Configurar customer user ID

Después de implementar la medición de eventos, configura una identidad persistente para vincular la actividad web con otras plataformas (móvil, PC, CTV) utilizando setCustomerUserId, con el fin de obtener una vista unificada del viaje del usuario entre plataformas.

Reglas clave

  • Consistencia: Utiliza el mismo valor de CUID que en las implementaciones de tu app móvil (consulta el setCustomerUserId móvil para: iOS, Android, Unity).
  • Cuándo: Puedes enviar el CUID en cualquier etapa (por ejemplo, después del inicio de sesión o del registro). Configura el CUID tan pronto como sea posible, una vez que tengas acceso a él. La mayoría de las veces, esto significa que debes esperar a que el usuario se identifique mediante inicio de sesión o registro.
  • Sintaxis: Envía el valor como una cadena de texto (entre comillas). Ejemplo: AF('pba', 'setCustomerUserId', '663274')
  • Privacidad: No incluyas información de identificación personal (PII), como direcciones de correo electrónico o números de teléfono.
Ejemplo: Configuración de CUID después del registro (nativo)

El código proporcionado en estos ejemplos es solo de referencia. No utilices este código tal cual. Si no estás seguro de cómo utilizar este código, consulta con tu desarrollador web.

Supuesto: Web SDK ya está cargado en la página antes de enviar el evento; no lo cargues nuevamente.

Escenario del usuario:

  • Un usuario se registra en tu sitio web.
  • El código del sitio web recopila los datos del usuario y los envía a tu servidor.
  • El servidor genera un CUID único para el usuario.
  • En la página de agradecimiento posterior al registro, consultas al servidor para obtener el nuevo CUID.
  • Utilizando la respuesta del servidor, configuras el CUID de AppsFlyer mediante el método setCustomerUserId() de Web SDK.

Ejemplo de formulario de registro

El siguiente código es un formulario de registro simple. Cuando se envía el formulario, la dirección de correo electrónico se almacena en localStorage. Cuando el usuario llega a la página de agradecimiento, la dirección de correo electrónico se envía al servidor para obtener el CUID único asociado a ese correo.

<html>
<head>
    <script>
        (function (w, d, s, l, i) {
            w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
            var f = d.getElementsByTagName(s)[0], j = d.createElement(s),
                dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true;
            j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
            f.parentNode.insertBefore(j, f);
        })(window, document, 'script', 'dataLayer', 'GTM-5VJ6C7R');
        function storeUserEmail() {
            var userEmail = document.getElementById('email').value;
            localStorage.setItem('user_email', userEmail);
        }
    </script>
</head>
<body>
    <h1>Sign Up</h1>
    <form onsubmit="storeUserEmail()" action="/signup" method="post">
        <div><label>Name</label><input type="text" name="name" id="name"></div>
        <br />
        <div><label>Email</label><input type="email" name="email" id="email"></div>
        <br />
        <input type="submit" id="submit">
    </form>
</body>
</html>

Ejemplo de página de agradecimiento

El código utiliza la API Fetch. Envía al servidor la dirección de correo electrónico ingresada por el usuario. Suponiendo que el servidor crea un usuario con un CUID único al registrarse, enviar la dirección de correo electrónico al servidor devuelve un CUID único. El servidor responde con un CUID único, y este CUID es el valor que se envía mediante el método setCustomerUserId.

General
Ejemplo: Configuración de CUID después del registro (Google Tag Manager)
  1. Configura una página de registro.

    El ejemplo de código a continuación es un formulario de registro simple. Cuando se envía el formulario, la dirección de correo electrónico se almacena en localStorage. Cuando el usuario llega a la página de agradecimiento, la dirección de correo electrónico se envía al servidor para obtener el CUID único asociado a ese correo.

    <html>
    <head>
        <script>
            (function (w, d, s, l, i) {
                w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
                var f = d.getElementsByTagName(s)[0], j = d.createElement(s),
                    dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true;
                j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
                f.parentNode.insertBefore(j, f);
            })(window, document, 'script', 'dataLayer', 'GTM-5VJ6C7R');
            function storeUserEmail() {
                var userEmail = document.getElementById('email').value;
                localStorage.setItem('user_email', userEmail);
            }
        </script>
    </head>
    <body>
        <h1>Registro</h1>
        <form onsubmit="storeUserEmail()" action="/signup" method="post">
            <div><label>Nombre</label><input type="text" name="name" id="name"></div>
            <br />
            <div><label>Correo electrónico</label><input type="email" name="email" id="email"></div>
            <br />
            <input type="submit" id="submit">
        </form>
    </body>
    </html>
  2. Configura una página de agradecimiento para los usuarios que se registran. El siguiente código corresponde a una página de agradecimiento con un activador de GTM que envía al servidor la dirección de correo electrónico proporcionada por el usuario en el formulario de registro. Suponiendo que el servidor crea un usuario con un CUID único al registrarse, enviar el correo electrónico al servidor devuelve un CUID único. El servidor responde con un CUID único, que se envía utilizando el método setCustomerUserId().

    <script>
        window.onload = function () {
            var userEmail = localStorage.getItem('user_email');
            fetch('users/' + userEmail).then(function (res) {
                res.text().then(function (id) {
                    console.log(id);
                    AF('pba', 'setCustomerUserId', id);
                });
            });
        }
    </script>
  3. Agrega una nueva etiqueta para atribuir suscripciones después de que se cargue la página de agradecimiento.

    Añadir una nueva etiqueta de GTM para el evento de conversión de CUID
  4. Asigna un nombre distintivo a la etiqueta y selecciona la opción de tipo de etiqueta HTML personalizado.

    Asignar un nombre a la etiqueta y seleccionar el tipo de etiqueta HTML personalizado en GTM
    <script>
        var userEmail = localStorage.getItem('user_email');
        fetch('users/' + userEmail).then(function (res) {
            res.text().then(function (id) {
                console.log(id);
                AF('pba', 'setCustomerUserId', id);
            });
        });
    </script>
  5. Expande Configuración avanzada y luego Secuenciación de etiquetas debajo del área de texto, y asegúrate de que esté configurado para activar la conversión después de que se ejecute la etiqueta.

    Configurar la secuenciación de etiquetas de GTM para la etiqueta de conversión
  6. Configura un activador para la etiqueta de conversión que indique cuándo debe ejecutarse (en el ejemplo siguiente, se ejecuta al cargar la página de "Gracias").

    Configurar el activador de GTM para que active la etiqueta de conversión al cargar la página de agradecimiento

7. Gestionar la privacidad

Después de implementar la medición de eventos, es posible que debas aplicar restricciones específicas de seguridad y privacidad para cumplir con estándares organizacionales o regionales.

Activar o desactivar el envío de eventos

Puedes controlar la medición de dos maneras:

Configuración del estado inicial del SDK (en el snippet)

Determina si el SDK envía eventos cuando la página web se carga por primera vez o si espera hasta que le indiques explícitamente que comience a enviarlos. Esta configuración se define en el snippet web.

  • Enviar eventos: {pba: {webAppId: "...", measurementStatus:true}}
  • No enviar eventos: {pba: {webAppId: "...", measurementStatus:false}}

Si measurementStatus está vacío o es NULL, AppsFlyer lo considera como si measurementStatus:true.

Control explícito

El control explícito tiene prioridad sobre la configuración del estado inicial y utiliza cookies persistentes de first-party:

  • Se establecen en el dominio del sitio web.
  • Expiran después de un período definido por Web SDK o por el navegador.
  • Siempre están sujetas a la configuración de cookies del navegador.

Comandos

  • Comenzar a enviar eventos (opt-in): window.AF_SDK.PLUGINS.PBA.enableMeasurement()
  • Dejar de enviar eventos (opt-out): window.AF_SDK.PLUGINS.PBA.disableMeasurement()
Proteger y filtrar datos

Si tu sitio web requiere estrictos protocolos de seguridad o privacidad de datos, utiliza los siguientes mecanismos para configurar cómo interactúa el SDK web con tu entorno y tus datos.

Política de Seguridad de Contenido (CSP)

Si tu sitio web requiere que JavaScript esté protegido mediante una CSP, Web SDK admite dos enfoques según tu configuración de CSP y el snippet que seleccionaste en el Paso 2.

  • CSP usando self: Agrega https://websdk.appsflyersdk.com a tu lista script-src de permitidos. Esto funciona tanto para Standard Web SDK como para Advanced SDK Verification.
  • CSP utilizando nonce: Si tu política utiliza script-src 'nonce-...', usa la variante de Advanced SDK Verification extendida con nonce que aparece a continuación. Esto reenvía el nonce a las tres etiquetas script que requiere el proceso de verificación. Reemplaza {{CSP_NONCE}} con tu valor nonce generado por el servidor, por solicitud.

La siguiente tabla muestra qué políticas de CSP son compatibles con la variante nonce-extended.

Política Funciona Notas
script-src 'self' No No se permite el origen de CDN externo; el script en línea también se bloquea.
script-src 'self' https://websdk.appsflyersdk.com Parcial Permite el loader y el SDK, pero el script de configuración en línea sigue bloqueado.
script-src 'nonce-...' https://websdk.appsflyersdk.com Nonce cubre el script en línea y el loader; la etiqueta del SDK es reenviada por el loader.
script-src 'nonce-...' 'strict-dynamic' Sí (recomendado) Nonce cubre el script en línea y el loader; strict-dynamic propaga confianza a la etiqueta del SDK inyectada dinámicamente. No se necesita origen de CDN en la lista de permitidos.
Compatibilidad con políticas de CSP

Advanced SDK Verification con fragmentos de CSP nonce

Sin Smart Banners
<script nonce="{{CSP_NONCE}}">
  // Queue — buffers AF() calls until the SDK is ready
  window. AppsFlyerSdkObject = "AF";
  window. AF = window. AF || function() {
    (window.AF.q = window. AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
  };
  window. AF.id = window. AF.id || { pba: { webAppId: "WEB_DEV_KEY" } };
  window. AF.plugins = {};

  // Manifest loader config — nonce forwarded to the injected SDK <script> tag
  window. AF_LOADER_CONFIG = {
    baseUrl: "https://websdk.appsflyersdk.com",
    plugins: ["pba"],
    nonce: "{{CSP_NONCE}}"
  };

  // Inject manifest loader
  var loaderScript = document.createElement("script");
  loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
  loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
  loaderScript.crossOrigin = "anonymous";
  loaderScript.nonce = "{{CSP_NONCE}}";
  loaderScript.async = true;
  document.head.appendChild(loaderScript);
</script>
Con Smart Banners
<script nonce="{{CSP_NONCE}}">
  // Queue — buffers AF() calls until the SDK is ready
  window. AppsFlyerSdkObject = "AF";
  window. AF = window. AF || function() {
    (window.AF.q = window. AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
  };
  window. AF.id = window. AF.id || { pba: { webAppId: "WEB_DEV_KEY" }, banners: { key: "YOUR_BANNER_KEY" } };
  window. AF.plugins = {};

  // Manifest loader config — nonce forwarded to the injected SDK <script> tag
  window. AF_LOADER_CONFIG = {
    baseUrl: "https://websdk.appsflyersdk.com",
    plugins: ["banners", "pba"],
    nonce: "{{CSP_NONCE}}"
  };

  // Inject manifest loader
  var loaderScript = document.createElement("script");
  loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
  loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
  loaderScript.crossOrigin = "anonymous";
  loaderScript.nonce = "{{CSP_NONCE}}";
  loaderScript.async = true;
  document.head.appendChild(loaderScript);
</script>

Descartar parámetros de consulta

Si los parámetros de consulta de tu URL contienen información sensible, indica a AppsFlyer que los descarte (URLs, referrers y header_referer).

  • Descartar todos los parámetros de consulta: agrega af_url=true
  • Descartar parámetros específicos: utiliza af_url_mask=param (separa varios parámetros con ;)

Ejemplo:

  • Original: param1=value1&param2=value2&param3=value3&af_url_mask=param2;param3
  • Resultado: param1=value1&af_url_mask=param2;param3

Referencia de cookies de Web SDK

Web SDK establece o utiliza las siguientes cookies:

Nombre de la cookie Dominio Vida útil Cuando se utiliza Detalles
afUserid El dominio de tu sitio web 395 días Páginas móviles no aceleradas Identifica a un usuario en el contexto de eventos de carga y navegación de páginas web.
AF_SYNC El dominio de tu sitio web 1 semana Páginas móviles no aceleradas Indica que se ha establecido un identificador de usuario final. Se utiliza para reducir los tiempos de carga del sitio.
af_id appsflyer.com 395 días Páginas móviles no aceleradas cuando se permiten cookies de terceros Identifica a un usuario en el contexto de eventos de apertura y navegación de la app.
af_id onelink.me 395 días Páginas móviles no aceleradas cuando se permiten cookies de terceros Vincula interacciones con banners, interacciones con OneLink o ambas con eventos de apertura de la app.
amp-afUserid AMP CDN o el dominio de tu sitio web 1 año Páginas móviles aceleradas
AF_DEFAULT_MEASUREMENT_STATUS El dominio de tu sitio web 395 días Páginas móviles no aceleradas Almacena el estado del consentimiento. Impide que el SDK funcione hasta que el usuario otorgue su consentimiento. No se configura de forma predeterminada. Se utiliza únicamente cuando está configurado control de consentimiento.