Web SDK - Guía de implementación de Google Tag Manager

Documento

Vista general

INFORMACIÓN: Web Attribution es una función para empresas. Póngase en contacto con su Customer Success Manager para habilitar esta función en su cuenta.

Esta guía explica cómo implementar Singular Web SDK mediante Google Tag Manager (GTM). Este método es ideal para equipos sin acceso directo al código del sitio web o para aquellos que deseen gestionar el seguimiento a través de GTM.

IMPORTANTE No utilice ambas implementaciones, GTM y JavaScript nativo, en el mismo sitio. Elija sólo un método para evitar duplicar el seguimiento e inflar los recuentos de eventos. Singular no deduplica eventos automáticamente.

  • No implemente ambos métodos, Native JavaScript y Google Tag Manager. Elija sólo uno para evitar el seguimiento duplicado.
  • Singular Web SDK está diseñado para ejecutarse en el navegador del usuario. Requiere acceso a funciones del navegador como localStorage y el Modelo de objetos del documento (DOM) para funcionar correctamente. No intente ejecutar el SDK del lado del servidor (por ejemplo, a través de Next.js SSR o node.js), ya que esto provocará fallos en el seguimiento, puesto que los entornos de servidor no proporcionan acceso a las API del navegador.

Requisitos previos

Antes de empezar, asegúrese de que dispone de

Pasos de implementación


Paso 1: Añada las plantillas de Singular Web Tracking a su contenedor GTM

  1. Acceda a su cuenta de Google Tag Manager y seleccione el contenedor de su sitio web.
  2. Vaya a Etiquetas > Nueva.
  3. Asigne un nombre a la etiqueta"Etiqueta Singular Init"
  4. Haga clic en el cuadro Configuración de etiqueta para comenzar la configuración de la etiqueta.
  5. Elija Tipo de etiqueta: y seleccione "Descubra más tipos de etiquetas en la Galería de plantillas de la comunidad".
  6. Busque "Singular" y seleccione "Singular Web Tracking". Haga clic en el botón "Añadir al área de trabajo".

Paso 2: Inicializar el SDK

  1. Complete los campos del formulario con lo siguiente:
    • Establezca el Tipo de seguimiento como Inicialización
    • Introduzca su SDK Key real en el campo Api Key.
    • Introduzca su SDK Secret real en el campo Secret.
    • Introduzca su ID de producto real. Debe parecerse a: com.website-name y debe coincidir con el valor de BundleID en la página Apps en la plataforma Singular.

      SUGERENCIA: utilice un ID de producto específico para probar com.website-name.dev y actualícelo antes de enviarlo a producción. Esto mantiene todos sus datos de prueba separados de la aplicación de producción en los informes de Singular.

    • Opcional:
      • Nivel de registro: La configuración del registro de depuración de SDK en la consola. El valor predeterminado es ninguno.
      • Tiempo de espera de la sesión: Cuánto tiempo tiene que estar inactivo el usuario antes de que el SDK cree una nueva sesión. Singular envía las sesiones de usuario para calcular la retención de usuarios y permitir la atribución de reenganche. El valor por defecto es 30 minutos.
      • Seguimiento entre subdominios
  2. Seleccione Disparador para configurar un disparador para que esta etiqueta funcione.
  3. Elija Nuevo y nombre el Tigger"Singular Init Trigger".
  4. Haga clic en la configuración del disparador y elija"Vista de página - Ventana cargada" y haga clic en"Guardar".
  5. Haga clic en"Guardar" de nuevo para guardar la etiqueta.
  6. Haga clic en"Vista previa" de la página de la etiqueta y compruebe que se activa la etiqueta de inicialización singular.

    singular_init_tag_fired.png

¡ÉXITO! Si ve la etiqueta "Singular Init Tag" en la sección de etiquetas activadas de la consola de vista previa, significa que ha configurado correctamente la etiqueta de inicialización.

IMPORTANTE! para SPAs (Single Page Applications), debe activar el trackType Page Visit cada vez que se dirija a una página diferente. No llame a Visita de Página en la primera página que se carga ya que la Inicialización ya informa de una visita de página.

Solución

  • Utilice una variable JavaScript personalizada para detectar si es la primera página que se carga.
  • Configure 2 Etiquetas:
    • "Singular Init Tag" (Track Type = Initialization) para que se dispare sólo en la carga inicial de la página.
    • "Etiqueta deVisita de Página Singular" (Tipo de Pista = Visita de Página) para disparar en cada cambio de ruta (excluyendo la carga inicial) usando el disparador de Cambio de Historial.
  • Asegúrese de que su SPA envía eventos de historial al dataLayer para los cambios de ruta.

image5.png


Paso 3: Seguimiento de eventos

Después de inicializar el SDK, puede rastrear eventos personalizados cuando los usuarios realicen acciones importantes en su sitio web.

IMPORTANTE Singular no bloquea los eventos duplicados. Es responsabilidad del desarrollador añadir protecciones contra los refrescos de página o la duplicación. Se recomienda incorporar algún método de deduplicación específico para los eventos de ingresos para evitar datos erróneos de ingresos. Consulte el "Paso 5: Prevención de eventos duplicados" a continuación para ver un ejemplo..

Basic EventConversion EventRevenue Event

Seguimiento básico de eventos

Realice el seguimiento de un evento simple o añada atributos personalizados utilizando JSON válido para proporcionar más contexto sobre el evento:

  1. Cree una nueva Etiqueta para su Evento personalizado utilizando la plantilla Singular Web Tracking.

  2. Asigne un nombre a la etiqueta de evento.

  3. Elija Tipo de seguimiento = Evento personalizado

  4. Ajuste el campo "Nombre del Evento" o establezca la variable apropiada.

  5. Ajuste el campo "ID de usuario personalizado" o establezca la variable adecuada.

  6. Ajuste los "Atributos" si lo desea para pasar pares Clave/Valor en el Evento.

  7. Configure un Activador adecuado para disparar la Etiqueta sólo cuando se espere.

  8. Guarde el Activador y la Etiqueta, y pruébelos en la Vista Previa.

custom_event.png

Patrones comunes de implementación de eventos

Page Load EventsButton Click EventsForm Submission Events

Creación de activadores GTM para eventos de carga de página

Para implementar Singular Web SDK con Google Tag Manager, deberá crear un activador de carga de página que se dispare cuando se carguen las páginas.

Configuración rápida: En GTM, vaya a Activadores Nueva configuración de activadores y seleccione "Vista de página" como tipo de activador. Para la mayoría de las implementaciones, elija "Todas las vistas de página" para activar el disparador en cada carga de página.

Para obtener instrucciones de configuración completas: Consulte la documentación oficial de Google Tag Manager:


Paso 4: Configuración del ID de usuario del cliente

Puede enviar su ID de usuario interno a Singular utilizando un método de Singular SDK.

NOTA: Si utiliza la solución Cross-Device de Singular, debe recopilar el ID de usuario en todas las plataformas.

NOTA: Si varios usuarios utilizan un único dispositivo, recomendamos implementar un flujo de cierre de sesión para establecer y desestablecer el ID de usuario para cada inicio y cierre de sesión.

CONSEJO Utilice el mismo ID de usuario de cliente que utiliza en sus SDK móviles. Esto permite la atribución entre dispositivos y proporciona una visión completa del comportamiento del usuario en todas las plataformas.

Mientras el usuario realice acciones en su sitio web sin haber iniciado sesión, los eventos se envían a Singular con un ID de usuario generado por Singular. Pero después de que el usuario se registre o inicie sesión, puede hacer que los eventos se envíen a Singular junto con el ID de usuario que se utiliza en su sitio web, por ejemplo, una dirección de correo electrónico con hash.

Singular utiliza el identificador de usuario en las exportaciones de datos a nivel de usuario (consulte Exportación de registros de atribución), así como en los postbacks de BI internos, si los tiene configurados (consulte Configuración de postbacks de BI internos).

Hay dos formas de enviar el ID de usuario a Singular:

  • Recomendado: Si conoce el ID de usuario cuando se abre el sitio web, configure el ID de usuario en el tipo de pista Inicialización al inicializar el SDK. De este modo, el ID de usuario estará disponible para Singular desde la primera visita a la página.
  • Como alternativa, puede activar una etiqueta con el tipo de pista = Inicio de sesión en cualquier momento, normalmente después de que se produzca una autenticación. Nota: la activación de esta etiqueta no desencadena ningún evento. Sólo establece el ID de usuario que se añadirá a cualquier evento que se active en el futuro.

Para establecer el ID de usuario con Singular, añada una etiqueta Singular con el tipo de seguimiento "Inicio de sesión":

  1. En su cuenta de Google Tag Manager, haga clic en Etiquetas > Nueva.
  2. En la ventana de configuración de etiquetas, haz clic en Configuración de etiquetas y, en el menú Tipo de etiqueta, selecciona "Seguimiento web singular".
  3. En Tipo de seguimiento, seleccione "Inicio de sesión".
  4. En ID de usuario personalizado, introduzca la variable de Google Tag Manager que contiene el ID de usuario.
  5. Haga clic en Activación y añada el evento de activación: inicio de sesión o registro del usuario.
  6. Haga clic en Guardar.

image4.png

Para desactivar el ID de usuario, añada una etiqueta con el tipo de seguimiento " Cierre de sesión":

  1. En su cuenta de Google Tag Manager, haga clic en Etiquetas > Nuevo.
  2. En la ventana Configuración de etiquetas, haz clic en Configuración de etiquetas y, en el menú Tipo de etiqueta, selecciona "Seguimiento web singular".
  3. En Tipo de seguimiento, seleccione "Cierre de sesión".
  4. Haga clic en Activación y añada el evento de activación: cierre de sesión de usuario.
  5. Haga clic en Guardar.

image1.png

Notas:

  • El ID de usuario persiste hasta que lo desactive utilizando el tipo de seguimiento de cierre de sesión o hasta que el usuario elimine su almacenamiento local.
  • Cerrar/reiniciar el sitio web no desactiva el ID de usuario.
  • Navegar en modo privado, como incógnito, evitará que Singular mantenga el ID de usuario, ya que el almacenamiento local se elimina automáticamente al cerrar el navegador.

Paso 5: Prevención de eventos duplicados

Prevención de eventos duplicados en Google Tag Manager

¡IMPORTANTE! Este es uno de los errores de implementación de GTM más comunes. Sin las protecciones adecuadas, los eventos del SDK de Singular Web pueden dispararse varias veces cuando los usuarios actualizan las páginas, vuelven a navegar o vuelven a activar acciones, lo que infla gravemente sus métricas.

Por qué se producen duplicados en GTM

Google Tag Manager evalúa los disparadores en cada carga de página, lo que provoca que las etiquetas se vuelvan a disparar cuando los usuarios actualizan las páginas de agradecimiento, vuelven a enviar formularios o navegan con los botones atrás/adelante del navegador. Esto ocurre porque GTM carece de conocimiento de sesión integrado para los eventos personalizados.


Métodos de deduplicación de GTM

Método de almacenamiento de sesiones: Almacenar identificadores de evento únicos en el sessionStorage del navegador para realizar un seguimiento de los eventos que ya se han disparado durante la sesión del usuario.

Variables JavaScript personalizadas: Crear variables que comprueben el localStorage en busca de eventos disparados previamente antes de permitir que se disparen otros nuevos.

Condiciones de activación: Añada lógica condicional a los activadores para evitar que se activen cuando haya indicadores duplicados.


Pasos de implementación

Crear Variable de Almacenamiento: Cree una variable JavaScript personalizada que genere identificadores únicos para cada evento singular en función de los parámetros del evento y de la sesión del usuario.

Crear variable de comprobación: Cree otra Variable JavaScript Personalizada que compruebe si el identificador de evento actual ya existe en el almacenamiento del navegador.

Añada condiciones de activación: Modifique sus disparadores de Singular Web SDK para incluir una condición de que la variable "duplicate check" sea igual a "false".

Almacenar después de disparar: Utilice la función de secuenciación de etiquetas de GTM para disparar una etiqueta HTML personalizada que almacene el identificador de evento en sessionStorage después de que el evento Singular se dispare correctamente.


Consideraciones específicas de GTM

Secuenciación de etiquetas: Utilice la función de secuenciación de etiquetas de la configuración avanzada para asegurarse de que las etiquetas de almacenamiento se activan después de que se hayan completado las etiquetas singulares principales.

Evaluación de variables: Recuerde que las variables JavaScript personalizadas se evalúan cada vez que se hace referencia a ellas, así que optimice el rendimiento.

Limitaciones entre dominios: SessionStorage es específico del dominio, así que implemente soluciones basadas en cookies para el seguimiento entre dominios si es necesario.

Para una implementación detallada: Consulte las guías completas de deduplicación de GTM:


Paso 6: Probar la implementación de GTM

  1. Abra el modo de vista previa de GTM y cargue su sitio web.
  2. Compruebe que
  • El SDK se carga (solicitud de red a singular-sdk.js)
  • Los eventos se activan como se espera y sólo una vez por acción
  • No hay errores en la consola del navegador relacionados con singular
  • Las solicitudes de red se envían a sdk-api-v1.singular.net
  1. Utilice la pestaña Red en las herramientas de desarrollo del navegador para verificar que se envía la carga útil adecuada.

ÉXITO Si ve eventos singulares correctos en las solicitudes de red y no hay duplicados, ¡está listo para empezar!


Paso 7: Implementar el Reenvío de Web a App

Reenvío de atribuciones de Web a App

Utilice Singular Web SDK para realizar un seguimiento de los viajes de los usuarios desde su sitio web a su aplicación móvil, lo que permite una atribución precisa de la campaña web a las instalaciones de aplicaciones móviles y reengagements. Siga estos pasos para configurar el reenvío de web a aplicación, incluyendo el soporte de código QR para los usuarios de escritorio.

  1. Siga nuestra Guía de Reenvío de Atribuciónde Sitio Web a AplicaciónMóvil para configurar el SDK de Singular Web para la atribución web móvil.
  2. Para el seguimiento de Web a aplicación de escritorio:
    • Creación de una etiqueta de limpieza del generador de códigos QR
      1. Vaya a Etiquetas > Nuevo en GTM y seleccione HTML personalizado.
      2. Añada código a:
        • Inyectar la biblioteca QRCode que elija
        • Recuperar el enlace Web-to-App de window.singularSdk.buildWebToAppLink(baselink);
        • Generar el QRCode a partir del enlace devuelto.
        • Actualizar la imagen QRCode en la página.
      3. Nombre la etiqueta "Singular - Generador de código QR (Limpieza)"
      4. No necesita activador: Las etiquetas de limpieza heredan los activadores de la etiqueta principal.
      5. Configure su etiqueta Singular Init:
        • Haga clic en Configuración de etiquetas
        • Vaya a Configuración avanzada > Secuenciación de etiquetas
        • Marque "Disparar una etiqueta de limpieza después de que se dispare [Etiqueta Singular Init]"
        • Seleccione su etiqueta QR Code Generator en el menú desplegable.
        • Guarde la etiqueta y pruébela en modo Vista previa.

CONSEJO Las vistas web del navegador de la aplicación móvil (como las utilizadas por Facebook, Instagram y TikTok) pueden hacer que el ID de dispositivo de Singular cambie si un usuario cambia al navegador nativo del dispositivo, lo que interrumpe la atribución.

Para evitarlo, utilice siempre el formato de enlace de seguimiento Singular adecuado para cada red publicitaria:


Temas avanzados

Añadir propiedades globales

Propiedades globales
#

El SDK de Singular le permite definir propiedades personalizadas para ser enviadas a los servidores de Singular junto con cada sesión y evento enviado desde la aplicación. Estas propiedades pueden representar cualquier información que desee sobre el usuario, el modo/estado de la aplicación o cualquier otra cosa.

  • Puedes definir hasta 5 propiedades globales como un objeto JSON válido. Las propiedades globales se mantienen en el navegador localstorage hasta que se borra o se cambia el contexto del navegador.

  • Cada nombre y valor de propiedad puede tener hasta 200 caracteres. Si pasas un nombre o valor de propiedad más largo, se truncará a 200 caracteres.

  • Las propiedades globales se reflejan actualmente en los registros de eventos a nivel de usuario de Singular (véase Exportación de registros de atribución) y en los postbacks.

  • Las propiedades globales están disponibles para mí enviadas en postbacks desde Singular a un tercero para propósitos de correspondencia es necesario.

La configuración de una propiedad global antes de la inicialización del SDK no se admite actualmente con la etiqueta de inicialización de Google Tag Manager. Sin embargo, para gestionar las propiedades globales después de la inicialización, debe crear etiquetas HTML personalizadas y ejecutar la función JavaScript nativa: setGlobalProperties() getGlobalProperties() , clearGlobalProperties().

Creación de una etiqueta HTML personalizada para gestionar las propiedades globales

  1. En la interfaz de Google Tag Manager, haga clic en Etiquetas en el menú de navegación izquierdo y, a continuación, en el botón Nuevo para crear una nueva etiqueta.

  2. Haz clic en Configuración de etiquetas y selecciona HTML personalizado en la lista de tipos de etiquetas disponibles.

  3. En el campo HTML, pegue el código del método de propiedad global. Consulte las opciones a continuación:

  4. Haga clic en Activación y asigne una opción de activación a la etiqueta.

  5. Dé a su etiqueta un nombre descriptivo como "Singular - Establecer Propiedades Globales" en el campo de nombre de etiqueta en la parte superior.

Al establecer las Propiedades Globales, la Propiedad Global persistirá en todos los eventos hasta que se desactive o se borre.

Haga clic en Vista previa para probar su implementación. Verifique en la consola del navegador que las propiedades globales están establecidas.

Para una configuración avanzada: Consulte la documentación oficial de Google sobre HTML personalizado

Setting Global PropertiesGetting GlobalPropertiesClearing Global Properties

Código de etiqueta HTML personalizada para establecer propiedades globales

<script>
/**
 * Set a Singular global property before SDK initialization.
 * Allows up to 5 key/value pairs. Optionally overwrites existing value for a key.
 * 
 * @param {string} propertyKey - The property key to set.
 * @param {string} propertyValue - The property value to set.
 * @param {boolean} overrideExisting - Whether to overwrite the property if it already exists.
 */

// Example usage - customize these values for your implementation
window.singularSdk.setGlobalProperties('user_type', 'premium', true);
window.singularSdk.setGlobalProperties('app_version', '2.1.0', false);
</script>

Seguimiento de búsquedas orgánicas

Ejemplo de seguimiento de búsqueda orgánica
#

Creación de la etiqueta de configuración de seguimiento de búsqueda orgánica

¡CRÍTICO!- Esta etiqueta debe activarse antes de la inicialización de Singular SDK.

Esta etiqueta HTML personalizada modifica la URL del documento para añadir parámetros de seguimiento de búsqueda orgánica (wpsrc y wpcn) que Singular Web SDK debe leer durante la inicialización. La secuencia de etiquetas es esencial para garantizar el orden de ejecución correcto.

Este ejemplo se proporciona como una solución alternativa para activar el seguimiento de búsqueda orgánica. El código debe utilizarse únicamente como ejemplo y debe ser actualizado y mantenido por el desarrollador web en función de las necesidades de su departamento de marketing. El seguimiento de búsqueda orgánica puede tener diferentes significados según el anunciante. Revise el ejemplo y ajústelo a sus necesidades.

¿Por qué utilizarlo?

  • Asegura que las visitas de búsqueda orgánica sean rastreadas correctamente, incluso si no hay parámetros de campaña presentes.

  • Añade el parámetro Singular "Source" wpsrccon el valor del (referrer) y el parámetro "Campaign Name" wpcn como "OrganicSearch" a la URL para una atribución clara.

  • Almacena la URL actual y el referente en localStoragepara su uso posterior.

  • Puro JavaScript, sin dependencias y fácil de integrar.

Cómo funciona

  1. Comprueba la URL de la página en busca de parámetros de campaña conocidos de (Google, Facebook, TikTok, UTMs, etc.).

  2. Si no hay parámetros de campaña presentes y el referente es un motor de búsqueda, añade:

    • wpsrc (con el referente como valor)
    • wpcn (con OrganicSearch como valor)
  3. Actualiza la URL en el navegador sin recargar la página.

  4. Almacena la URL actual y el referente en localStoragecomo sng_url y sng_ref.

Uso

  1. Vaya a Etiquetas > Nuevo en GTM y haga clic en Configuración de etiquetas, luego seleccione HTML personalizado.
  2. Pegue el código JavaScript completo como se muestra a continuación.
  3. Omita la creación del disparador para esta etiqueta.Dado que esta etiqueta debe ejecutarse antes de la etiqueta Singular Init, la configuraremos para que se dispare antes de la Init utilizando la secuenciación de etiquetas.

    1. Utilice un nombre descriptivo como "Singular - Configuración de búsqueda orgánica".
    2. Abra su Singular Web SDK Init Tag.
    3. Haga clic en Configuración de etiquetas
    4. Vaya a Configuración avanzada > Secuenciación de etiquetas.
    5. Marque "Disparar una etiqueta de configuración antes de que se dispare [Singular Init Tag]".
    6. Seleccione su etiqueta "Singular - Organic Search Setup" del menú desplegable.
    7. Recomendado: Marque "No disparar [Etiqueta de inicio singular] si [etiqueta de configuración] falla" para evitar la inicialización con una modificación incompleta de la URL.
    8. organic_search.png
    9. Guarde la etiqueta.
  4. Utiliza el modo de vista previa de GTM para verificarlo:

    • La etiqueta de configuración se dispara primero y modifica la URL.
    • La etiqueta Singular Init se dispara en segundo lugar y lee los parámetros de URL modificados.
    • No se producen conflictos de sincronización entre las etiquetas.

Para la secuenciación avanzada de etiquetas: Consulte la documentación oficial de Google:


Organic Search Tracking Code
<script>
(function() {
    // singular-web-organic-search-tracking: setupOrganicSearchTracking.js
    // Tracks organic search referrals by appending wpsrc and wpcn to the URL if no campaign parameters exist and the referrer is a search engine.

    // Configuration for debugging (set to true to enable logs)
    var debug = true;

    // List of campaign parameters to check for exclusion
    var campaignParams = [
        'gclid', 'fbclid', 'ttclid', 'msclkid', 'twclid', 'li_fat_id',
        'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'wpsrc'
    ];

    // Whitelist of legitimate search engine domains (prevents false positives)
    var legitimateSearchEngines = new Set([
        // Google domains
        'google.com', 'google.co.uk', 'google.ca', 'google.com.au', 'google.de', 
        'google.fr', 'google.it', 'google.es', 'google.co.jp', 'google.co.kr',
        'google.com.br', 'google.com.mx', 'google.co.in', 'google.ru', 'google.com.sg',
        
        // Bing domains  
        'bing.com', 'bing.co.uk', 'bing.ca', 'bing.com.au', 'bing.de',
        
        // Yahoo domains
        'yahoo.com', 'yahoo.co.uk', 'yahoo.ca', 'yahoo.com.au', 'yahoo.de',
        'yahoo.fr', 'yahoo.it', 'yahoo.es', 'yahoo.co.jp',
        
        // Other search engines
        'baidu.com', 'duckduckgo.com', 'yandex.com', 'yandex.ru',
        'ask.com', 'aol.com', 'ecosia.org', 'startpage.com', 
        'qwant.com', 'seznam.cz', 'naver.com', 'daum.net'
    ]);

    // Extract main domain from hostname (removes subdomains)
    function getMainDomain(hostname) {
        if (!hostname) return '';
        
        var lowerHost = hostname.toLowerCase();
        
        // Handle special cases for known search engines with country codes
        var searchEnginePatterns = {
            'google': function(host) {
                // Match google.TLD patterns more precisely
                if (host.indexOf('google.co.') !== -1 || host.indexOf('google.com') !== -1) {
                    var parts = host.split('.');
                    for (var i = 0; i < parts.length - 1; i++) {
                        if (parts[i] === 'google') {
                            return parts.slice(i).join('.');
                        }
                    }
                }
                return null;
            },
            'bing': function(host) {
                if (host.indexOf('bing.co') !== -1 || host.indexOf('bing.com') !== -1) {
                    var parts = host.split('.');
                    for (var i = 0; i < parts.length - 1; i++) {
                        if (parts[i] === 'bing') {
                            return parts.slice(i).join('.');
                        }
                    }
                }
                return null;
            },
            'yahoo': function(host) {
                if (host.indexOf('yahoo.co') !== -1 || host.indexOf('yahoo.com') !== -1) {
                    var parts = host.split('.');
                    for (var i = 0; i < parts.length - 1; i++) {
                        if (parts[i] === 'yahoo') {
                            return parts.slice(i).join('.');
                        }
                    }
                }
                return null;
            }
        };
        
        // Try specific patterns for major search engines
        for (var engine in searchEnginePatterns) {
            if (lowerHost.indexOf(engine) !== -1) {
                var result = searchEnginePatterns[engine](lowerHost);
                if (result) return result;
            }
        }
        
        // Handle other known engines with simple mapping
        var otherEngines = {
            'baidu.com': 'baidu.com',
            'duckduckgo.com': 'duckduckgo.com', 
            'yandex.ru': 'yandex.ru',
            'yandex.com': 'yandex.com',
            'ask.com': 'ask.com',
            'aol.com': 'aol.com',
            'ecosia.org': 'ecosia.org',
            'startpage.com': 'startpage.com',
            'qwant.com': 'qwant.com',
            'seznam.cz': 'seznam.cz',
            'naver.com': 'naver.com',
            'daum.net': 'daum.net'
        };
        
        for (var domain in otherEngines) {
            if (lowerHost.indexOf(domain) !== -1) {
                return otherEngines[domain];
            }
        }
        
        // Fallback: Extract main domain by taking last 2 parts (for unknown domains)
        var parts = hostname.split('.');
        if (parts.length >= 2) {
            return parts[parts.length - 2] + '.' + parts[parts.length - 1];
        }
        
        return hostname;
    }

    // Get query parameter by name, using URL.searchParams with regex fallback for IE11
    function getParameterByName(name, url) {
        if (!url) url = window.location.href;
        try {
            return new URL(url).searchParams.get(name) || null;
        } catch (e) {
            if (debug) console.warn('URL API not supported, falling back to regex:', e);
            name = name.replace(/[\[\]]/g, '\\$&');
            var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
            var results = regex.exec(url);
            if (!results) return null;
            if (!results[2]) return '';
            return decodeURIComponent(results[2].replace(/\+/g, ' '));
        }
    }

    // Check if any campaign parameters exist in the URL
    function hasAnyParameter(url, params) {
        for (var i = 0; i < params.length; i++) {
            if (getParameterByName(params[i], url) !== null) {
                return true;
            }
        }
        return false;
    }

    // Improved search engine detection - only checks hostname, uses whitelist
    function isSearchEngineReferrer(referrer) {
        if (!referrer) return false;
        
        var hostname = '';
        try {
            hostname = new URL(referrer).hostname.toLowerCase();
        } catch (e) {
            // Fallback regex for hostname extraction (IE11 compatibility)
            var match = referrer.match(/^(?:https?:\/\/)?([^\/\?#]+)/i);
            hostname = match ? match[1].toLowerCase() : '';
        }
        
        if (!hostname) return false;
        
        // First check: exact match against whitelist
        if (legitimateSearchEngines.has(hostname)) {
            if (debug) console.log('Exact match found for:', hostname);
            return true;
        }
        
        // Second check: subdomain of legitimate search engine
        var hostParts = hostname.split('.');
        if (hostParts.length >= 3) {
            // Try domain.tld combination (e.g., google.com from www.google.com)
            var mainDomain = hostParts[hostParts.length - 2] + '.' + hostParts[hostParts.length - 1];
            if (legitimateSearchEngines.has(mainDomain)) {
                if (debug) console.log('Subdomain match found for:', hostname, '-> main domain:', mainDomain);
                return true;
            }
            
            // Try last 3 parts for country codes (e.g., google.co.uk from www.google.co.uk)
            if (hostParts.length >= 3) {
                var ccDomain = hostParts[hostParts.length - 3] + '.' + hostParts[hostParts.length - 2] + '.' + hostParts[hostParts.length - 1];
                if (legitimateSearchEngines.has(ccDomain)) {
                    if (debug) console.log('Country code domain match found for:', hostname, '-> cc domain:', ccDomain);
                    return true;
                }
            }
        }
        
        if (debug) {
            console.log('Hostname not recognized as legitimate search engine:', hostname);
        }
        
        return false;
    }

    // Main function to update URL with organic search tracking parameters
    function setupOrganicSearchTracking() {
        var url = window.location.href;
        var referrer = document.referrer || '';

        // Store URL and referrer in localStorage
        try {
            localStorage.setItem('sng_url', url);
            localStorage.setItem('sng_ref', referrer);
        } catch (e) {
            if (debug) console.warn('localStorage not available:', e);
        }

        if (debug) {
            console.log('Current URL:', url);
            console.log('Referrer:', referrer);
        }

        // Skip if campaign parameters exist or referrer is not a search engine
        var hasCampaignParams = hasAnyParameter(url, campaignParams);
        if (hasCampaignParams || !isSearchEngineReferrer(referrer)) {
            if (debug) console.log('Skipping URL update: Campaign params exist or referrer is not a legitimate search engine');
            return;
        }

        // Extract and validate referrer hostname
        var referrerHostname = '';
        try {
            referrerHostname = new URL(referrer).hostname;
        } catch (e) {
            if (debug) console.warn('Invalid referrer URL, falling back to regex:', e);
            var match = referrer.match(/^(?:https?:\/\/)?([^\/]+)/i);
            referrerHostname = match ? match[1] : '';
        }

        // Extract main domain from hostname
        var mainDomain = getMainDomain(referrerHostname);
        
        if (debug) {
            console.log('Full hostname:', referrerHostname);
            console.log('Main domain:', mainDomain);
        }

        // Only proceed if main domain is valid and contains safe characters
        if (!mainDomain || !/^[a-zA-Z0-9.-]+$/.test(mainDomain)) {
            if (debug) console.log('Skipping URL update: Invalid or unsafe main domain');
            return;
        }

        // Update URL with wpsrc and wpcn parameters
        var urlObj;
        try {
            urlObj = new URL(url);
        } catch (e) {
            if (debug) console.warn('URL API not supported, cannot modify URL:', e);
            return;
        }
        
        // Set wpsrc to the main domain (e.g., google.com instead of tagassistant.google.com)
        urlObj.searchParams.set('wpsrc', mainDomain);
        
        // Set wpcn to 'Organic Search' to identify the campaign type
        urlObj.searchParams.set('wpcn', 'Organic Search');

        // Update the URL without reloading (check if history API is available)
        if (window.history && window.history.replaceState) {
            try {
                window.history.replaceState({}, '', urlObj.toString());
                if (debug) console.log('Updated URL with organic search tracking:', urlObj.toString());
            } catch (e) {
                if (debug) console.warn('Failed to update URL:', e);
            }
        } else {
            if (debug) console.warn('History API not supported, cannot update URL');
        }
    }

    // Execute the function
    setupOrganicSearchTracking();
})();
</script>

Seguimiento entre subdominios

Por defecto, el SDK de Singular Website genera un ID de Dispositivo Singular y lo persiste utilizando el almacenamiento del navegador. Dado que este almacenamiento no puede compartirse entre subdominios, el SDK acaba generando un nuevo ID para cada subdominio.

Si desea mantener el ID de dispositivo singular en todos los subdominios, puede utilizar una de las siguientes opciones:

Método B (Avanzado): Establezca el ID de dispositivo singular manualmente
#

Método B (Avanzado): Establecer ID de dispositivo singular manualmente

Si no desea que Singular SDK mantenga el ID de dispositivo automáticamente, puede mantener el ID manualmente en todos los dominios, por ejemplo, utilizando una cookie de dominio de nivel superior o una cookie de servidor. El valor debe ser un ID generado previamente por Singular en formato uuid4 válido.

Nota: Puede leer el ID del dispositivo Singular definiendo una variable JavaScript personalizada y llamando a singularSdk.getSingularDeviceId() después de llamar a la etiqueta Init track-type.

mceclip2.png


Problemas comunes de implementación de GTM

Identificadores de dispositivo necesarios
El evento se dispara varias veces Refine o limite sus disparadores, utilice "Una vez por página" o añada condiciones
Formato de ID de producto incorrecto El ID de producto debe utilizar la notación DNS inversa (com.company.site)
Eventos no rastreados Compruebe la ortografía y el uso de mayúsculas y minúsculas en los nombres de los eventos; asegúrese de que singularSDK está cargado antes de que se dispare la etiqueta del evento.
Script SDK bloqueado Bloqueadores de anuncios o política de seguridad de contenidos restrictiva; considere pasar a la implementación nativa de JS si los problemas persisten.

Mejores prácticas

  • Mantenga GTM organizado: Asigne un nombre claro a las etiquetas y los activadores y documente su finalidad.
  • Realice auditorías periódicas para detectar etiquetas no utilizadas o heredadas.
  • Minimice el número de activadores para reducir el riesgo de eventos duplicados.
  • Después de realizar cambios, pruébelos siempre a fondo en el modo de vista previa de GTM antes de lanzarlos.
  • Si utiliza el seguimiento basado en cookies(Cross-subdomain Tracking), actualice su política de privacidaden consecuencia.

Artículos relacionados