Visão geral
INFORMAÇÃO: A atribuição web é uma funcionalidade empresarial. Contacte o seu Gestor de Sucesso do Cliente para ativar esta funcionalidade na sua conta.
Este guia orienta a implementação do Singular WebSDK usando JavaScript nativo. Esse método oferece o rastreamento mais confiável e é recomendado para a maioria das implementações, pois não é bloqueado por bloqueadores de anúncios comuns.
IMPORTANTE!
- Não implemente os métodos JavaScript nativo e Google Tag Manager. Escolha apenas um para evitar rastreamento duplicado.
- O Singular WebSDK foi projetado para ser executado no lado do cliente, no navegador do usuário. Ele requer acesso a recursos do navegador, como localStorage e Document Object Model (DOM), para funcionar corretamente. Não tente executar o SDK no lado do servidor (por exemplo, via Next.js SSR ou node.js) — isso causará falhas no rastreamento, pois os ambientes de servidor não fornecem acesso às APIs do navegador.
Pré-requisitos
Antes de começar, certifique-se de ter:
-
Chave SDK e Segredo SDK:
- Onde encontrá-los: Faça login na sua conta Singular e navegue até Ferramentas do desenvolvedor > Integração do SDK > Chaves do SDK.
-
ID do produto:
-
O que é: um nome exclusivo para o seu site, idealmente usando o formato DNS reverso (por exemplo,
com.website-name). - Por que é importante: esse ID associa o site como um aplicativo no Singular e deve corresponder ao bundleID do aplicativo web listado na sua página de aplicativos no Singular.
-
O que é: um nome exclusivo para o seu site, idealmente usando o formato DNS reverso (por exemplo,
- Permissão para editar o código HTML do seu site.
- Acesso para adicionar JavaScript na seção
<head>das suas páginas. - Uma lista de eventos que você deseja rastrear. Veja nossos Eventos Padrão do Singular: Lista Completa e Eventos Recomendados por Vertical para obter ideias.
Etapas de implementação
Etapa 1: Adicione o script da biblioteca SDK
Adicione o seguinte trecho de código à seção <head> de todas as páginas do seu site. Coloque-o o mais cedo possível, de preferência próximo ao topo da tag <head>.
DICA! Adicionar o script logo no início garante que a biblioteca JavaScript do Singular esteja disponível para qualquer função do Singular no código-fonte da sua página.
<script src="https://web-sdk-cdn.singular.net/singular-sdk/latest/singular-sdk.js"></script>
Especifique a versão específica no caminho da biblioteca WebSDK JavaScript, por exemplo: 1.4.8 é indicado aqui:
<script src="https://web-sdk-cdn.singular.net/singular-sdk/1.4.8/singular-sdk.js"></script>
-
Execute
npm i singular-sdkno diretório raiz do seu projeto , ou adicione"singular-sdk": "^1.4.8"à seção de dependências no seu arquivo package.json e, em seguida, executenpm install. -
Adicione o seguinte código nos scripts que você deseja usar o SDK.
import {singularSdk, SingularConfig} from "singular-sdk";
Usando com Next.js / React
Next.js é uma estrutura React que fornece renderização do lado do servidor (SSR), geração de sites estáticos (SSG) e Componentes do Servidor React. Como o Singular WebSDK requer APIs do navegador (DOM, localStorage, cookies), você deve carregá-lo apenas no lado do cliente.
IMPORTANTE: Nunca carregue o Singular SDK em código do lado do servidor
(por exemplo, getServerSideProps, React Server Components ou
ambientes Node.js). Isso causará erros porque as APIs do navegador
não estão disponíveis no servidor.
Método 1: Usando o componente de script Next.js (recomendado)
O componente <Script> do Next.js fornece estratégias de carregamento otimizadas
e evita a injeção de scripts duplicados em
mudanças de rota.
// pages/_app.tsx (Pages Router) or app/layout.tsx (App Router)
import Script from 'next/script'
export default function App({ Component, pageProps }) {
return (
<>
<Script
src="https://web-sdk-cdn.singular.net/singular-sdk/latest/singular-sdk.js"
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
)
}
Opções de estratégia de script:
-
afterInteractive(recomendado): Carrega depois que a página se torna interativa - ideal para análises e rastreamento. -
lazyOnload: Carrega durante o tempo ocioso do navegador - use para widgets não críticos.
Método 2: Importação dinâmica para carregamento em nível de componente
Para controle no nível do componente, use importações dinâmicas do Next.js com
ssr: false para carregar o script somente quando necessário:
// pages/index.tsx
import dynamic from 'next/dynamic'
const SingularSDKLoader = dynamic(
() => import('../components/SingularSDKLoader'),
{ ssr: false }
)
export default function Page() {
return (
<div>
<SingularSDKLoader />
<h1>Your Page Content</h1>
</div>
)
}
// components/SingularSDKLoader.tsx
'use client' // Required for Next.js App Router
import { useEffect } from 'react'
export default function SingularSDKLoader() {
useEffect(() => {
// Load Singular SDK script dynamically
const script = document.createElement('script')
script.src = 'https://web-sdk-cdn.singular.net/singular-sdk/latest/singular-sdk.js'
script.async = true
document.body.appendChild(script)
// Cleanup on unmount
return () => {
if (document.body.contains(script)) {
document.body.removeChild(script)
}
}
}, [])
return null
}
Configuração de variáveis de ambiente
DICA! Armazene suas credenciais Singular em variáveis de ambiente
prefixadas com NEXT_PUBLIC_ para torná-las
disponíveis no navegador:
# .env.local
NEXT_PUBLIC_SINGULAR_SDK_KEY=your_sdk_key_here
NEXT_PUBLIC_SINGULAR_SDK_SECRET=your_sdk_secret_here
NEXT_PUBLIC_SINGULAR_PRODUCT_ID=com.your-website
Essas variáveis de ambiente estarão acessíveis no seu código do lado do cliente e podem ser usadas durante a inicialização na Etapa 2.
Roteador de aplicativos vs roteador de páginas
| Tipo de roteador | Principais diferenças | Localização do script |
|---|---|---|
| Roteador de aplicativos (Next.js 13+) |
Os componentes são componentes do servidor por padrão. Adicione
a diretiva 'use client' para APIs do navegador.
|
app/layout.tsx
|
| Roteador de páginas (Next.js 12 e versões anteriores) | Todos os componentes são componentes do cliente por padrão. |
pages/_app.tsx
|
Etapa 2: Inicialize o SDK
- Sempre inicialize o SDK cada vez que uma página for carregada no navegador.
- A inicialização é necessária para todos os recursos de atribuição e rastreamento de eventos do Singular.
- A inicialização aciona um
__PAGE_VISIT__evento. - O
__PAGE_VISIT__evento é usado para gerar uma nova sessão no lado do servidor quando as seguintes condições são atendidas:- O usuário chega com novos dados de publicidade na URL (como parâmetros UTM ou WP) ou
- A sessão anterior expirou (após 30 minutos de inatividade).
- As sessões são usadas para medir a retenção de usuários e apoiar a atribuição de reengajamento.
- Crie uma função de inicialização e chame essa função no DOM Ready após o carregamento da página.
- Certifique-se de que a inicialização ocorra antes que quaisquer outros eventos Singular sejam relatados.
- Para aplicativos de página única (SPA), inicialize o SDK Singular no primeiro carregamento da página e, em seguida, chame a função Singular Page Visist
window.singularSdk.pageVisit()em cada mudança de rota que represente uma nova visualização de página.
Inicialização básica DOM-Ready
Adicione um ouvinte de eventos para chamar o initSingularSDK()
em DOMContentLoaded
/**
* Initializes the Singular SDK with the provided configuration.
* @param {string} sdkKey - The SDK key for Singular.
* @param {string} sdkSecret - The SDK secret for Singular.
* @param {string} productId - The product ID for Singular.
* @example
* initSingularSDK(); // Initializes SDK with default config
*/
function initSingularSDK() {
var config = new SingularConfig('sdkKey', 'sdkSecret', 'productId');
window.singularSdk.init(config);
}
/**
* Triggers Singular SDK initialization when the DOM is fully parsed.
*/
document.addEventListener('DOMContentLoaded', function() {
initSingularSDK();
});
Inicialização básica com propriedades globais
Como o SDK Singular não está inicializado, você deve implementar
a função personalizada para definir as propriedades globais no
localstorage do navegador.
Consulte a função personalizada setGlobalPropertyBeforeInit().
Depois de implementada, você pode definir as propriedades conforme descrito abaixo antes da
inicialização do SDK.
/**
* Initializes the Singular SDK with the provided configuration.
* @param {string} sdkKey - The SDK key for Singular.
* @param {string} sdkSecret - The SDK secret for Singular.
* @param {string} productId - The product ID for Singular.
* @example
* initSingularSDK(); // Initializes SDK with default config
*/
function initSingularSDK() {
var sdkKey = 'sdkKey';
var sdkSecret = 'sdkSecret';
var productId = 'productId';
// Set global properties before SDK initialization
setGlobalPropertyBeforeInit(sdkKey, productId, 'global_prop_1', 'test', false);
setGlobalPropertyBeforeInit(sdkKey, productId, 'global_prop_2', 'US', true);
// Initialize SDK
var config = new SingularConfig('sdkKey', 'sdkSecret', 'productId');
window.singularSdk.init(config);
}
/**
* Triggers Singular SDK initialization when the DOM is fully parsed.
*/
document.addEventListener('DOMContentLoaded', function() {
initSingularSDK();
});
Inicialização básica com roteamento de aplicativo de página única (SPA)
| Cenário | O que fazer |
|---|---|
|
Primeiro carregamento da página |
Chame |
|
Navegando para uma nova rota/página |
Chame |
|
No carregamento inicial no SPA |
Não chame |
Exemplo para SPAs (React)
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
/**
* Initializes the Singular SDK with the provided configuration.
* @param {string} sdkKey - The SDK key for Singular.
* @param {string} sdkSecret - The SDK secret for Singular.
* @param {string} productId - The product ID for Singular.
* @example
* // Initialize the Singular SDK
* initSingularSDK();
*/
function initSingularSDK() {
var config = new SingularConfig('sdkKey', 'sdkSecret', 'productId');
window.singularSdk.init(config);
}
/**
* Tracks a page visit event with the Singular SDK on route changes.
* @example
* // Track a page visit
* trackPageVisit();
*/
function trackPageVisit() {
window.singularSdk.pageVisit();
}
/**
* A React component that initializes the Singular SDK on mount and tracks page visits on route changes.
* @returns {JSX.Element} The component rendering the SPA content.
* @example
* // Use in a React SPA with react-router-dom
* function App() {
* const location = useLocation();
* useEffect(() => {
* initSingularSDK();
* }, []);
* useEffect(() => {
* trackPageVisit();
* }, [location.pathname]);
* return <div>Your SPA Content</div>;
* }
*/
function App() {
const location = useLocation();
useEffect(() => {
initSingularSDK();
}, []); // Run once on mount for SDK initialization
useEffect(() => {
trackPageVisit();
}, [location.pathname]); // Run on route changes for page visits
return (
<div>Your SPA Content</div>
);
}
export default App;
Inicialização básica usando um callback de inicialização
Se você precisar executar o código após o SDK estar pronto (por exemplo, para obter
o Singular
Device ID), defina um callback com .withInitFinishedCallback():
/**
* Initializes the Singular SDK with a callback to handle initialization completion.
* @param {string} sdkKey - The SDK key for Singular.
* @param {string} sdkSecret - The SDK secret for Singular.
* @param {string} productId - The product ID for Singular.
* @example
* initSingularSDK(); // Initializes SDK and logs device ID
*/
function initSingularSDK() {
var config = new SingularConfig('sdkKey', 'sdkSecret', 'productId')
.withInitFinishedCallback(function(initParams) {
var singularDeviceId = initParams.singularDeviceId;
// Example: Store device ID for analytics
console.log('Singular Device ID:', singularDeviceId);
// Optionally store in localStorage or use for event tracking
// localStorage.setItem('singularDeviceId', singularDeviceId);
});
window.singularSdk.init(config);
}
/**
* Triggers Singular SDK initialization when the DOM is fully parsed.
*/
document.addEventListener('DOMContentLoaded', function() {
initSingularSDK();
});
Inicialização Next.js / React
Após carregar o script do SDK na Etapa 1, inicialize-o quando o DOM estiver pronto. A inicialização deve ocorrer no lado do cliente após o script ter sido carregado.
Declarações de tipo TypeScript
Crie um arquivo de declaração de tipo para adicionar suporte a TypeScript para o Singular SDK:
// types/singular.d.ts
interface SingularConfig {
new (sdkKey: string, sdkSecret: string, productId: string): SingularConfig;
withCustomUserId(userId: string): SingularConfig;
withAutoPersistentSingularDeviceId(domain: string): SingularConfig;
withLogLevel(level: number): SingularConfig;
withSessionTimeoutInMinutes(timeout: number): SingularConfig;
withProductName(productName: string): SingularConfig;
withPersistentSingularDeviceId(singularDeviceId: string): SingularConfig;
withInitFinishedCallback(callback: (params: { singularDeviceId: string }) => void): SingularConfig;
}
interface SingularSDK {
init(config: SingularConfig): void;
event(eventName: string, attributes?: Record<string, any>): void;
conversionEvent(eventName: string): void;
revenue(eventName: string, currency: string, amount: number, attributes?: Record<string, any>): void;
login(userId: string): void;
logout(): void;
pageVisit(): void;
buildWebToAppLink(baseLink: string): string;
getSingularDeviceId(): string;
setGlobalProperties(key: string, value: string, override: boolean): void;
getGlobalProperties(): Record<string, string>;
clearGlobalProperties(): void;
}
interface Window {
singularSdk: SingularSDK;
SingularConfig: typeof SingularConfig;
}
Inicialização básica com o componente de script Next.js
Ao usar o componente Script da Etapa 1, adicione a chamada de retorno onLoad
para inicializar o SDK:
// pages/_app.tsx or app/layout.tsx
import Script from 'next/script'
export default function App({ Component, pageProps }) {
return (
<>
<Script
src="https://web-sdk-cdn.singular.net/singular-sdk/latest/singular-sdk.js"
strategy="afterInteractive"
onLoad={() => {
// Initialize Singular SDK after script loads
const config = new (window as any).SingularConfig(
process.env.NEXT_PUBLIC_SINGULAR_SDK_KEY,
process.env.NEXT_PUBLIC_SINGULAR_SDK_SECRET,
process.env.NEXT_PUBLIC_SINGULAR_PRODUCT_ID
);
window.singularSdk.init(config);
}}
/>
<Component {...pageProps} />
</>
)
}
Inicialização com o hook useEffect
Se você estiver usando o método de importação dinâmica ou precisar de mais controle, inicialize
usando useEffect:
// components/SingularInitializer.tsx
'use client'
import { useEffect } from 'react'
export default function SingularInitializer() {
useEffect(() => {
// Wait for script to load, then initialize
const checkAndInit = () => {
if (window.singularSdk && window.SingularConfig) {
const config = new window.SingularConfig(
process.env.NEXT_PUBLIC_SINGULAR_SDK_KEY!,
process.env.NEXT_PUBLIC_SINGULAR_SDK_SECRET!,
process.env.NEXT_PUBLIC_SINGULAR_PRODUCT_ID!
);
window.singularSdk.init(config);
} else {
// Retry if SDK not loaded yet
setTimeout(checkAndInit, 100);
}
};
checkAndInit();
}, []); // Empty dependency - run once on mount
return null;
}
Inicialização com opções de configuração
Encadeie métodos .with para habilitar recursos adicionais, como
rastreamento entre subdomínios ou IDs de usuário personalizados:
const config = new window.SingularConfig(
process.env.NEXT_PUBLIC_SINGULAR_SDK_KEY!,
process.env.NEXT_PUBLIC_SINGULAR_SDK_SECRET!,
process.env.NEXT_PUBLIC_SINGULAR_PRODUCT_ID!
)
.withAutoPersistentSingularDeviceId('your-domain.com')
.withCustomUserId(userId)
.withLogLevel(2); // 0=None, 1=Warn, 2=Info, 3=Debug
window.singularSdk.init(config);
Roteamento de aplicativo de página única (SPA)
Para aplicativos Next.js com roteamento do lado do cliente, você precisa rastrear as alterações de rota separadamente da inicialização inicial.
IMPORTANTE: Inicialize o SDK apenas uma vez na primeira
carregada da página. Em seguida, chame window.singularSdk.pageVisit()
em cada alteração de rota subsequente.
// components/SingularPageTracker.tsx
'use client'
import { useEffect, useRef } from 'react'
import { usePathname } from 'next/navigation' // App Router
// or import { useRouter } from 'next/router' // Pages Router
export default function SingularPageTracker() {
const pathname = usePathname() // App Router
// const router = useRouter(); const pathname = router.pathname // Pages Router
const isInitialized = useRef(false);
// Initialize SDK once on mount
useEffect(() => {
if (!isInitialized.current && window.singularSdk && window.SingularConfig) {
const config = new window.SingularConfig(
process.env.NEXT_PUBLIC_SINGULAR_SDK_KEY!,
process.env.NEXT_PUBLIC_SINGULAR_SDK_SECRET!,
process.env.NEXT_PUBLIC_SINGULAR_PRODUCT_ID!
);
window.singularSdk.init(config);
isInitialized.current = true;
}
}, []); // Empty dependency - runs once
// Track page visits on route changes (NOT on initial mount)
useEffect(() => {
if (isInitialized.current && window.singularSdk) {
window.singularSdk.pageVisit();
}
}, [pathname]); // Runs when pathname changes
return null;
}
Usando uma chamada de retorno de inicialização
Se você precisar executar código após o SDK estar pronto (por exemplo, para obter
o ID do dispositivo Singular), use .withInitFinishedCallback():
const config = new window.SingularConfig(
process.env.NEXT_PUBLIC_SINGULAR_SDK_KEY!,
process.env.NEXT_PUBLIC_SINGULAR_SDK_SECRET!,
process.env.NEXT_PUBLIC_SINGULAR_PRODUCT_ID!
)
.withInitFinishedCallback((initParams) => {
const singularDeviceId = initParams.singularDeviceId;
console.log('Singular Device ID:', singularDeviceId);
// Store for analytics or pass to other services
});
window.singularSdk.init(config);
Melhores práticas para inicialização do Next.js
- Inicialize o SDK apenas uma vez na montagem do aplicativo, não em cada mudança de rota.
-
Use variáveis de ambiente com o prefixo
NEXT_PUBLIC_para credenciais do SDK. -
Para SPAs, chame
window.singularSdk.pageVisit()nas mudanças de rota para rastrear a navegação. -
Use
useRefpara rastrear o estado de inicialização e evitar inicializações duplicadas. -
Adicione verificações nulas para
window.singularSdkantes de chamar métodos para evitar erros durante o SSR. - Teste no modo de desenvolvimento para garantir que o SDK seja inicializado corretamente sem erros do lado do servidor.
Lista de verificação do desenvolvedor para Next.js
- Verifique se o script foi carregado com sucesso na Etapa 1.
- Configure variáveis de ambiente com suas credenciais do SDK.
- Crie declarações de tipo TypeScript para uma melhor experiência do desenvolvedor .
-
Escolha o método de inicialização: componente de script
onLoadou hookuseEffect. -
Para SPAs, implemente o rastreamento de alterações de rota com
pageVisit(). -
Teste a inicialização verificando o console para o
evento
__PAGE_VISIT__.
-
Substitua
'sdkKey'pela sua chave SDK real. -
Substitua
'sdkSecret'pelo seu segredo SDK real. -
Substitua
'productId'pelo seu ID do produto real. Deve ficar assim:com.website-namee deve corresponder ao valor BundleID na página Apps na plataforma Singular.
Opções de configuração
Aprimore a configuração do WebSDK encadeando métodos .with para habilitar recursos extras.
Por exemplo, para oferecer suporte ao rastreamento entre subdomínios, mantendo o Singular Device ID (SDID) em um cookie ou para incluir um ID de usuário personalizado para um visitante que retorna ao site com um estado de login ativo:
var domain = 'website-name.com';
var config = new SingularConfig('sdkKey','sdkSecret','productId')
.withAutoPersistentSingularDeviceId(domain)
.withCustomUserId(userId);
Referência do método SingularConfig
Aqui estão todos os métodos ".with" disponíveis.
| Método | Descrição | Saiba mais |
.withCustomUserId(customId)
|
Enviar o ID do usuário para o Singular | Definir o ID do usuário |
.withProductName(productName)
|
Um nome de exibição opcional para o produto | |
.withLogLevel(logLevel)
|
Configure o nível de registro: 0 - Nenhum (padrão); 1 - Aviso; 2 - Informação; 3 - Depuração. | |
.withSessionTimeoutInMinutes(timeout)
|
Defina o tempo limite da sessão em minutos (padrão: 30 minutos) |
|
.withAutoPersistentSingularDeviceId(domain)
|
Habilitar rastreamento automático entre subdomínios | Persistência automática usando cookies |
|
|
Ativar rastreamento manual entre subdomínios | Definir manualmente o ID único do dispositivo |
.withInitFinishedCallback(callback)
|
Chamar um callback quando a inicialização do SDK estiver concluída | Chamar uma função de retorno de chamada quando a inicialização estiver concluída |
.withGlobalProperties(globalProperties, false)
|
Definir propriedades globais durante a inicialização; o segundo parâmetro
é overrideExisting (booleano).
Use false para mesclar com as propriedades existentes,
true para sobrescrever as propriedades existentes.
|
Propriedades globais |
.withEventsDedupEnabled()
|
Habilite a deduplicação opcional de eventos para reduzir a exportação de eventos duplicados (por exemplo, gatilhos repetidos disparados em um curto intervalo) | Deduplicação de eventos |
.withTimeBetweenEvents(timeBetweenEvents)
|
Defina a janela de tempo máxima (ms) para deduplicação (padrão: 1000 ms / 1 segundo) | Deduplicação de eventos |
Lista de verificação do desenvolvedor
- Reúna suas credenciais SDK e ID do produto.
- Decida se você precisa de configurações personalizadas (ID do usuário, tempo limite, etc.).
- Crie uma função de inicialização Singular e um objeto SingularConfig usando os exemplos acima.
- Sempre teste para garantir que a inicialização seja acionada apenas uma vez ao carregar a página.
Etapa 3: Rastreamento de eventos
Após inicializar o SDK, você pode rastrear eventos personalizados quando os usuários realizam ações importantes em seu site.
IMPORTANTE! O Singular não bloqueia eventos duplicados! É responsabilidade dos desenvolvedores adicionar proteções contra atualizações ou duplicações de página. Recomenda-se incorporar algum método de deduplicação específico para eventos de receita, a fim de evitar dados de receita errôneos. Veja "Etapa 5: Prevenção de eventos duplicados" abaixo para um exemplo.
Rastreamento básico de eventos
Rastreie um evento simples ou adicione atributos personalizados usando JSON válido para fornecer mais contexto sobre o evento:
// Basic event tracking
var eventName = 'page_view';
window.singularSdk.event(eventName);
// Optional: With attributes for more context
var eventName = 'sng_content_view';
var attributes = {
key1: 'value1', // First custom attribute
key2: 'value2' // Second custom attribute
};
window.singularSdk.event(eventName, attributes);
Rastreamento de eventos de conversão
Rastreie um evento de conversão:
var eventName = 'sng_complete_registration';
window.singularSdk.conversionEvent(eventName);
Rastreamento de eventos de receita
Rastreie eventos de conversão com informações de receita e adicione atributos opcionais para obter mais contexto:
- Passe a moeda da receita como um código de moeda ISO 4217 de três letras, como “USD”, “EUR” ou “INR”.
- Passe o valor da receita como um valor decimal.
// Revenue event tracking
var revenueEventName = 'sng_ecommerce_purchase';
var revenueCurrency = 'USD';
var revenueAmount = 49.99;
window.singularSdk.revenue(revenueEventName, revenueCurrency, revenueAmount);
// Optional: With attributes for more context
var revenueEventName = 'sng_ecommerce_purchase';
var revenueCurrency = 'USD';
var revenueAmount = 49.99;
var attributes = {
key1: 'value1', // First custom attribute
key2: 'value2' // Second custom attribute
};
window.singularSdk.revenue(revenueEventName, revenueCurrency, revenueAmount, attributes);
Padrões comuns de implementação de eventos
Eventos de carregamento de página
O mecanismo de rastreamento de eventos de carregamento de página usa JavaScript para monitorar
quando uma página da web é totalmente carregada e, em seguida, aciona um evento de análise usando
o SDK Singular. Especificamente, ele utiliza o
método window.addEventListener('load', ...) para detectar
quando todos os recursos da página (por exemplo, HTML, imagens, scripts) foram carregados.
Após esse evento, a função event do SDK Singular é
chamada para registrar um evento personalizado com atributos associados, permitindo
o rastreamento das interações do usuário para fins de análise, como monitorar
visualizações de página ou ações do usuário, como registros. O mecanismo é comumente
usado em análises da web para capturar dados sobre o comportamento do usuário, como
visitas à página ou ações específicas, com atributos personalizáveis para
insights detalhados.
O mecanismo pode ser adaptado para rastrear um evento específico (por exemplo, um
evento page_view ) com atributos personalizados, conforme mostrado
abaixo. A estrutura do código permanece limpa e modular, com o nome do evento
e os atributos definidos separadamente para maior clareza e facilidade de manutenção.
/**
* Tracks a registration event with the Singular SDK when the page fully loads.
* @param {string} eventName - The name of the event to track (e.g., 'page_view').
* @param {Object} attributes - A JSON object with custom event attributes.
* @param {string} attributes.key1 - First custom attribute (e.g., 'value1').
* @param {string} attributes.key2 - Second custom attribute (e.g., 'value2').
*/
window.addEventListener('load', function() {
var eventName = 'page_view';
var attributes = {
key1: 'value1', // First custom attribute
key2: 'value2' // Second custom attribute
};
window.singularSdk.event(eventName, attributes);
});
Eventos de clique no botão
O mecanismo de rastreamento de eventos de clique em botões usa JavaScript para monitorar
quando um usuário clica em um botão com o ID checkout-button
e aciona um evento checkout_started usando o Singular
SDK para rastreamento analítico. O código emprega um ouvinte de eventos click
para detectar a interação com o botão, inclui um mecanismo
para evitar múltiplos acionamentos de eventos (usando um
atributo data-event-fired ) e envia o evento com
atributos personalizados (cart_value e currency)
para a plataforma Singular. Isso é ideal para análises de comércio eletrônico
para rastrear quando os usuários iniciam um processo de checkout, garantindo dados precisos
ao disparar o evento apenas uma vez por sessão da página.
/**
* Tracks a checkout started event with the Singular SDK when a button is clicked.
* @param {string} eventName - The name of the event to track (e.g., 'checkout_started').
* @param {Object} attributes - A JSON object with custom event attributes.
* @param {number} attributes.cart_value - The total value of the cart (e.g., 99.99).
* @param {string} attributes.currency - The currency of the cart value (e.g., 'USD').
*/
document.getElementById('checkout-button').addEventListener('click', function(e) {
// Prevent multiple fires
if (this.hasAttribute('data-event-fired')) {
return;
}
this.setAttribute('data-event-fired', 'true');
var eventName = 'checkout_started';
var attributes = {
cart_value: 99.99, // Total value of the cart
currency: 'USD' // Currency of the cart value
};
window.singularSdk.event(eventName, attributes);
});
Eventos de envio de formulário
O mecanismo de rastreamento de eventos de envio de formulário usa JavaScript para monitorar
quando um usuário envia um formulário com o ID signup-form e
aciona um evento signup_completed usando o Singular
SDK para rastreamento analítico. O código emprega um submit
event listener para detectar o envio do formulário, inclui um mecanismo para
evitar múltiplos acionamentos de eventos (usando um data-event-fired
attribute) e envia o evento com um atributo personalizado (signup_method)
para a plataforma Singular. Isso é ideal para rastrear inscrições de usuários
em fluxos de trabalho de análise, como monitorar métodos de aquisição ou inscrição de usuários
, garantindo dados precisos ao disparar o evento apenas uma vez por
sessão da página.
Abaixo está um exemplo simples que adapta o código original para usar
window.singularSdk.event , separando o nome do evento
e os atributos para maior clareza.
/**
* Tracks a signup completed event with the Singular SDK when a form is submitted.
* @param {string} eventName - The name of the event to track (e.g., 'signup_completed').
* @param {Object} attributes - A JSON object with custom event attributes.
* @param {string} attributes.signup_method - The method used for signup (e.g., 'email').
* @example
* // Track a signup event with additional attributes
* var eventName = 'signup_completed';
* var attributes = {
* signup_method: 'email',
* email: document.getElementById('email')?.value || 'unknown'
* };
* window.singularSdk.event(eventName, attributes);
*/
document.getElementById('signup-form').addEventListener('submit', function(e) {
// Prevent multiple fires
if (this.hasAttribute('data-event-fired')) {
return;
}
this.setAttribute('data-event-fired', 'true');
var eventName = 'signup_completed';
var attributes = {
signup_method: 'email' // Method used for signup
};
window.singularSdk.event(eventName, attributes);
});
Etapa 4: Definir o ID do usuário do cliente
Você pode enviar sua ID de usuário interna para o Singular usando um método SDK do Singular.
NOTA: Se você usar a solução Cross-Device da Singular, deverá coletar a ID do usuário em todas as plataformas.
- A ID do usuário pode ser qualquer identificador e não deve expor PII (informações de identificação pessoal). Por exemplo, você não deve usar o endereço de e-mail, nome de usuário ou número de telefone de um usuário. A Singular recomenda o uso de um valor hash exclusivo apenas para seus dados primários .
- O valor do ID do usuário passado para o Singular também deve ser o mesmo ID interno do usuário que você captura em todas as plataformas (Web/Mobile/PC/Console/Offline).
- A Singular incluirá a ID do usuário em exportações no nível do usuário, ETL e postbacks internos de BI (se configurados). A ID do usuário é um dado primário, e a Singular não a compartilha com terceiros.
- O valor do ID do usuário, quando definido com o método Singular SDK, permanecerá até ser desativado usando o método logout() ou até que o armazenamento local do navegador seja excluído. Fechar ou atualizar o site não desativa o ID do usuário.
- No modo privado/incógnito, o SDK não pode manter a ID do usuário porque o navegador exclui automaticamente o armazenamento local quando é fechado.
Para definir a ID do usuário, use o método login().
Para
desativá-la (por exemplo, se o usuário "sair" da conta), chame o método
logout() .
NOTA: Se vários usuários usarem um único dispositivo, recomendamos implementar um fluxo de logout para definir e desativar o ID do usuário para cada login e logout.
Se você já souber o ID do usuário quando o SDK Singular for inicializado no
site,
defina o ID do usuário no objeto de configuração. Dessa forma, o Singular pode ter o ID do usuário
desde a primeira sessão. No entanto, o ID do usuário normalmente não está disponível até
o
O usuário se registra ou faz login. Nesse caso, chame login() após a conclusão do fluxo de registro.
DICA! Use o mesmo ID de usuário do cliente que você usa em seus SDKs móveis. Isso permite a atribuição entre dispositivos e fornece uma visão completa do comportamento do usuário em todas as plataformas.
Práticas recomendadas para a ID de usuário do cliente:
- Defina-a assim que o usuário fizer login ou se cadastrar
- Use a mesma ID nas plataformas web e móveis
- Não use informações de identificação pessoal (e-mail, número de telefone)
- Use sua ID de usuário interna ou ID de banco de dados
- Envie como uma string, mesmo que seja numérica:
// After user logs in or signs up
var userId = 'user_12345';
window.singularSdk.login(userId);
// After user logs out
window.singularSdk.logout();
Etapa 5: Desduplicação de eventos (opcional)
IMPORTANTE! Se o seu site puder disparar o mesmo gatilho mais de uma vez em um curto intervalo de tempo, você poderá ver eventos duplicados exportados. Habilite a deduplicação do SDK para suprimir automaticamente as duplicatas.
O SDK da Web da Singular oferece suporte à deduplicação opcional de eventos para reduzir exportações duplicadas causadas por gatilhos repetidos disparados em um curto intervalo de tempo. Quando ativado, o SDK descartará eventos duplicados que correspondam aos mesmos parâmetros de deduplicação dentro do intervalo de tempo configurado.
Como ativar
-
withEventsDedupEnabled: Ative a deduplicação de eventos (o padrão é desativado). -
withTimeBetweenEvents: Janela de tempo máxima (em milissegundos) usada para considerar dois eventos duplicados; o padrão é 1000 ms (1 segundo).
JavaScript
// Enable optional event deduplication (recommended when triggers may fire repeatedly)
var config = new SingularConfig("SDK_KEY", "SDK_SECRET", "PRODUCT_ID")
.withEventsDedupEnabled() // turns deduplication on
.withTimeBetweenEvents(1000); // dedup window in ms (default: 1000 = 1s)
window.singularSdk.init(config);
Como as duplicatas são detectadas
Quando a deduplicação está ativada, o SDK calcula um hash a partir dos campos-chave do evento e suprime repetições dentro da janela de tempo. Os parâmetros de deduplicação incluem: EventName, EventProductName, IsRevenueEvent, CustomUserId, GlobalProperties, MatchId e WebUrl (e o SDK também leva em consideração cargas "extras" adicionais do evento, como receita/args, ao fazer o hash).
Etapa 6: Testando sua implementação
Após implementar o SDK, verifique se ele está funcionando corretamente usando as ferramentas de desenvolvedor do seu navegador.
Verifique se o SDK foi carregado
- Abra seu site em um navegador
- Abra as Ferramentas de desenvolvedor (F12 ou clique com o botão direito → Inspecionar)
- Vá para a guia Console
- Digite
typeof singularSdke pressione Enter - Você deverá ver um objeto "função", não "indefinido"
Verifique as solicitações de rede
- Abra as Ferramentas do desenvolvedor (F12)
- Vá para a guia Rede
- Recarregue a página
- Filtre por
singularousdk-api - Procure por solicitações para
sdk-api-v1.singular.net - Clique em uma solicitação para ver os detalhes
- Verifique se o código de status é
200 - Verifique se a carga útil da solicitação contém o ID do seu produto. Ele estará no parâmetro "
i" da carga útil.
SUCESSO! Se você vir solicitações para sdk-api-v1.singular.net com o código de status 200, seu SDK está enviando dados para o Singular com sucesso.
Verifique os eventos
- Acione um evento no seu site (clique em um botão, envie um formulário etc.).
- Na guia Rede, procure uma nova solicitação para
sdk-api-v1.singular.net - Clique na solicitação e visualize a guia Carga útil ou Solicitação
-
Verifique se o nome do seu evento "
n" aparece na solicitação
Para testes de ponta a ponta, use o Console de Testes
Você pode testar a integração do Web SDK usando o Console SDK disponível no painel do Singular.
- Na plataforma Singular, vá para Ferramentas do desenvolvedor > Console de testes.
- Clique em Adicionar dispositivo.
- Selecione a plataforma "Web" e insira o ID do dispositivo Singular.
- Obtenha o ID do dispositivo Singular na carga útil do navegador. Verifique a captura de tela acima para localizar o ID do dispositivo Singular (
SDID) em um evento. - O console de teste deve permanecer ativo enquanto você testa em uma janela separada. O console não exibirá nenhum evento acionado enquanto estiver fechado ou offline.
- Depois que o SDID for adicionado, você poderá recarregar a página da web e acionar alguns eventos. O "__PAGE_VISIT__" e outros eventos (se acionados) serão exibidos no Console SDK.
- Utilizar os logs de exportação (Reports & Insights Export Logs) é outra maneira de verificar os resultados dos testes. Esse conjunto de dados tem um atraso de 1 hora.
Etapa 7: implementar o encaminhamento da Web para o aplicativo
Encaminhamento de atribuição Web-to-App
Use o Singular WebSDK para rastrear as jornadas dos usuários do seu site para o seu aplicativo móvel, permitindo a atribuição precisa da campanha da web às instalações e reengajamentos do aplicativo móvel. Siga estas etapas para configurar o encaminhamento da web para o aplicativo, incluindo suporte a código QR para usuários de desktop.
- Siga nosso Guia de encaminhamento de atribuição do site para o aplicativo móvel para configurar o Singular WebSDK para atribuição da web móvel.
- Para rastreamento de desktop para aplicativo:
- Conclua a configuração no guia acima.
- Use o link do Singular Mobile Web-to-App (por exemplo,
https://yourlink.sng.link/...) e a função WebSDKbuildWebToAppLink(link)com uma biblioteca de códigos QR dinâmicos como QRCode.js. - Gere um código QR na sua página da Web que codifique o link. Os usuários de desktop podem digitalizá-lo com seus dispositivos móveis para abrir o aplicativo, passando os dados da campanha para atribuição.
- Explore nossa demonstração do Singular WebSDK para ver um exemplo prático de geração de código QR e gerenciamento de links web-to-app.
DICA! As visualizações da web no navegador do aplicativo móvel (como as usadas pelo Facebook, Instagram e TikTok) podem fazer com que o ID do dispositivo Singular mude se o usuário mudar para o navegador nativo do dispositivo, interrompendo a atribuição.
Para evitar isso, sempre use o formato de link de rastreamento Singular adequado para cada rede de anúncios:
Demonstração do Singular WebSDK
Abaixo está uma implementação simples, mas abrangente, usando a API Singular WebSDK documentada. Esta amostra fornece uma separação clara para eventos personalizados, eventos de conversão, eventos de receita e suporte a links da web para aplicativos usando o encaminhamento da web para aplicativos suportado pelo WebSDK.
Você pode executar este código em um arquivo HTML local ou modificá-lo em seu site para integração avançada e solução de problemas.
Copie e cole o código abaixo como um arquivo HTML e abra-o no seu navegador.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Singular WebSDK Demo</title>
<script src="https://cdn.jsdelivr.net/npm/qrcodejs/qrcode.min.js"></script>
<script src="https://web-sdk-cdn.singular.net/singular-sdk/latest/singular-sdk.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #1a1d29;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
padding: 40px 20px;
min-height: 100vh;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 48px;
border-radius: 16px;
box-shadow: 0 4px 24px rgba(30, 41, 59, 0.08);
border: 1px solid rgba(148, 163, 184, 0.1);
}
.header-brand {
display: flex;
align-items: center;
margin-bottom: 32px;
padding-bottom: 24px;
border-bottom: 2px solid #f1f5f9;
}
.brand-dot {
width: 12px;
height: 12px;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
border-radius: 50%;
margin-right: 12px;
}
h1 {
font-size: 32px;
font-weight: 700;
color: #0f172a;
letter-spacing: -0.025em;
}
h2 {
font-size: 24px;
font-weight: 600;
margin: 48px 0 24px 0;
color: #1e293b;
padding-bottom: 12px;
border-bottom: 2px solid #e2e8f0;
position: relative;
}
h2:before {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 60px;
height: 2px;
background: linear-gradient(90deg, #6366f1, #8b5cf6);
}
p {
margin-bottom: 18px;
color: #475569;
font-size: 15px;
}
strong {
color: #1e293b;
font-weight: 600;
}
.form-group {
margin-bottom: 24px;
}
.radio-group {
display: flex;
gap: 24px;
margin-bottom: 24px;
padding: 16px;
background: #f8fafc;
border-radius: 12px;
border: 1px solid #e2e8f0;
}
.radio-group label {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
color: #475569;
transition: color 0.2s ease;
}
.radio-group label:hover {
color: #1e293b;
}
input[type="radio"] {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: #6366f1;
}
input[type="text"] {
width: 100%;
padding: 14px 18px;
font-size: 15px;
font-weight: 400;
border: 2px solid #e2e8f0;
border-radius: 12px;
transition: all 0.2s ease;
background: #fafbfc;
color: #1e293b;
}
input[type="text"]:focus {
outline: none;
border-color: #6366f1;
background: white;
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
}
input[type="text"]::placeholder {
color: #94a3b8;
font-weight: 400;
}
button {
padding: 14px 32px;
font-size: 15px;
font-weight: 700;
color: #fff;
background: linear-gradient(90deg, #2363f6 0%, #1672fe 100%);
border: none;
border-radius: 4px; /* Pill shape */
cursor: pointer;
box-shadow: 0 2px 8px rgba(35, 99, 246, 0.12);
transition: background 0.2s, transform 0.2s;
letter-spacing: 0.03em;
}
button:hover {
background: linear-gradient(90deg, #1672fe 0%, #2363f6 100%);
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(22, 114, 254, 0.18);
}
button:active {
transform: translateY(0);
}
a {
color: #6366f1;
text-decoration: none;
font-weight: 600;
transition: all 0.2s ease;
position: relative;
}
a:hover {
color: #4f46e5;
}
a:after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: -2px;
left: 0;
background: #6366f1;
transition: width 0.2s ease;
}
a:hover:after {
width: 100%;
}
ol {
margin-left: 10px;
margin-bottom: 18px;
}
ol li {
margin-left: 10px;
}
.info-box {
background: linear-gradient(135deg, #eff6ff 0%, #f0f9ff 100%);
border-left: 4px solid #6366f1;
padding: 20px;
margin: 24px 0;
border-radius: 12px;
border: 1px solid rgba(99, 102, 241, 0.1);
}
.info-box p {
color: #1e40af;
margin-bottom: 0;
}
.section-label {
font-size: 12px;
font-weight: 700;
color: #6b7280;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.button-group {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.analytics-badge {
display: inline-flex;
align-items: center;
gap: 8px;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
color: white;
padding: 6px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
margin-bottom: 16px;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
margin: 24px 0;
}
.feature-item {
padding: 16px;
background: #f8fafc;
border-radius: 10px;
border: 1px solid #e2e8f0;
text-align: center;
}
.feature-item strong {
display: block;
color: #6366f1;
font-size: 14px;
margin-bottom: 4px;
}
.metric-dot {
width: 8px;
height: 8px;
background: #10b981;
border-radius: 50%;
display: inline-block;
margin-right: 8px;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
</style>
</head>
<body>
<div class="container">
<div class="header-brand">
<div class="brand-dot"></div>
<h1>Singular WebSDK Demo</h1>
</div>
<p>
Below is a simple but comprehensive implementation using the documented Singular WebSDK API.
This sample provides clear separation for <strong>custom events</strong>, <strong>conversion events</strong>, <strong>revenue events</strong>, and <strong>web-to-app link support using WebSDK supported Web-to-App forwarding</strong>. </p>
<p>You can run this code in a local HTML file or modify it in your site for advanced integration and troubleshooting.
</p>
<h2>SDK Initialization Testing</h2>
<ol>
<li>Open your browsers developer tools.</li>
<li>Inspect the Network tab and filter for "sdk-api-v1.singular.net"</li>
<li>Refresh this page, and examin the payload of the request.</li>
</ol>
<hr>
<h2>User Authentication</h2>
<p>User authentication is key to supporting cross-device attribution. Pass the common User ID value that would also be sent to Singular from mobile SDKs for cross-device continuity.</p>
<div class="form-group">
<div class="section-label">Simulate User Authentication</div>
<input type="text" id="userId" placeholder="Enter a User ID"/>
</div>
<div class="form-group">
<div class="button-group">
<button onclick="setUserId()">Set the User ID (Login)</button>
<button onclick="unsetUserId()">Unset the User ID (Logout)</button>
</div>
</div>
<hr>
<h2>SDK Event Testing</h2>
<div class="form-group">
<div class="section-label">Event Type Selection</div>
<div class="radio-group">
<label>
<input type="radio" name="eventType" value="custom" checked onchange="handleRevenueFields(this)">
<span>Custom Event</span>
</label>
<label>
<input type="radio" name="eventType" value="conversion" onchange="handleRevenueFields(this)">
<span>Conversion Event</span>
</label>
<label>
<input type="radio" name="eventType" value="revenue" onchange="handleRevenueFields(this)">
<span>Revenue Event</span>
</label>
</div>
</div>
<div class="form-group">
<div class="section-label">Event Configuration</div>
<input type="text" id="eventName" placeholder="Enter event name"/>
</div>
<div class="form-group" id="currencyGroup" style="display:none">
<input type="text" id="currency" placeholder="Currency code (e.g., USD, EUR)"/>
</div>
<div class="form-group" id="amountGroup" style="display:none">
<input type="text" id="amount" placeholder="Revenue amount (e.g., 29.99)"/>
</div>
<div class="form-group" id="attributesGroup" style="display:none">
<input type="text" id="attributes" placeholder='Optional attributes (JSON, e.g. {"color":"blue"})'/>
</div>
<div class="form-group">
<button id="send" onclick="sendCustomEvent()">Send Event to Singular</button>
</div>
<hr>
<h2>Web-to-App Forwarding</h2>
<div class="form-group">
<ol>
<li><a href="https://support.singular.net/hc/pt-br/articles/360042283811" target="_blank">Learn more about Web-to-App Forwarding</a></li>
<li>In the page source code you will find the mobile web-to-app base link "<strong>https://seteam.sng.link/D0mvs/y3br?_smtype=3</strong>" used for demonstration purposes.</li>
<li>Replace all occurances of the link with your own Singular Mobile Web-to-App link to test functionality.</li>
<li>Add Singular Web Parameters to the URL and refresh the page. (example: "<strong>?wpsrc=SingularTest&wpcn=MyCampaign</strong>").</li>
</ol>
<hr>
<div class="section-label">Mobile Web-to-App Test</div>
<div class="form-group">
<div class="button-group">
<button onclick="displayWebLink()">Display Constructed Web-to-App Link</button>
<button onclick="testWebLink()">Test Web-to-App Link</button>
</div>
</div>
</div>
<hr>
<div class="section-label">Desktop Web-to-App Configuration</div>
<div class="form-group">
<p>Use a dynamic QR Code generation library like <a href="https://davidshimjs.github.io/qrcodejs/" target="_blank">QRCode.js</a> to build and display a QR code using the Singular Mobile Web-to-App link with constructed campaign parameters.</p>
<div id="qrcode"></div>
</div>
</div>
<script>
/**
* Initializes the Singular SDK with the provided configuration.
* @param {string} sdkKey - The SDK key for Singular (e.g., 'se_team_9b3431b0').
* @param {string} sdkSecret - The SDK secret for Singular (e.g., 'bcdee06e8490949422c071437da5c5ed').
* @param {string} productId - The product ID for Singular (e.g., 'com.website').
* @example
* // Initialize the Singular SDK
* initSingularSDK('se_team_9b3431b0', 'bcdee06e8490949422c071437da5c5ed', 'com.website');
*/
function initSingularSDK() {
var sdkKey = 'se_team_9b3431b0';
var sdkSecret = 'bcdee06e8490949422c071437da5c5ed';
var productId = 'com.website';
// Global Properties set during init (plain object; max 5 keys persisted).
const globalProperties = {
plan: "pro",
region: "us"
};
// Applies to the whole object: false = merge with existing, true = clear existing then set.
const overrideExistingGlobalProperties = false; // required
const config = new SingularConfig(sdkKey, sdkSecret, productId)
.withLogLevel(3)
.withSessionTimeoutInMinutes(0.5)
.withGlobalProperties(globalProperties, overrideExistingGlobalProperties)
.withInitFinishedCallback(function (initParams) {
console.log("Singular Device ID:", initParams.singularDeviceId);
console.log("Global props (SDK):", window.singularSdk.getGlobalProperties());
// If you need to override just one key after init set it in the withInitFinishedCallback:
window.singularSdk.setGlobalProperties("plan", "enterprise");
});
// Initialize the Singular SDK
window.singularSdk.init(config);
generateDesktopWebToAppQRCode(); // Generate QR code after initialization
}
/**
* Triggers Singular SDK initialization when the DOM is fully parsed.
* @example
* document.addEventListener('DOMContentLoaded', function() {
* initSingularSDK();
* });
*/
document.addEventListener('DOMContentLoaded', function() {
initSingularSDK();
});
// Fires a custom event using the Singular SDK
function sendCustomEvent() {
var eventName = document.getElementById('eventName').value;
window.singularSdk.event(eventName);
}
// Fires a conversion event using the Singular SDK
function sendConversionEvent() {
var eventName = document.getElementById('eventName').value;
window.singularSdk.conversionEvent(eventName);
}
// Fires a revenue event only once per session with deduplication
// Parameters:
// - eventName: string (name of event), default "web_purchase" if blank
// - amount: revenue amount, default 0 if blank
// - currency: string, defaults to "USD" if blank
// - attributes: optional object with extra payload
function sendRevenueEvent(eventName, amount, currency, attributes) {
// Fill in defaults and normalize values
eventName = eventName ? eventName : "web_purchase";
currency = currency ? currency.toUpperCase() : "USD";
amount = amount ? amount : 0;
// Create a unique key based on event data for deduplication
// btoa(JSON.stringify(...)) ensures order consistency in local/sessionStorage
var payload = {
eventName: eventName,
amount: amount,
currency: currency,
attributes: attributes ? attributes : null
};
var storageKey = 'singular_revenue_' + btoa(JSON.stringify(payload));
// Only fire event if no identical event has already fired in this tab/session
if (!sessionStorage.getItem(storageKey)) {
sessionStorage.setItem(storageKey, 'true');
if (attributes && typeof attributes === 'object' && Object.keys(attributes).length > 0) {
// Fire event with attributes payload
window.singularSdk.revenue(eventName, currency, amount, attributes);
} else {
// Fire simple revenue event
window.singularSdk.revenue(eventName, currency, amount);
}
console.log("Revenue event sent:", payload);
} else {
// Duplicate detected, don't send to SDK
console.log("Duplicate revenue event prevented:", payload);
alert("Duplicate revenue event prevented!");
}
}
// Collects form values, validates attributes JSON, and calls sendRevenueEvent()
// Ensures only valid values are sent and blocks on malformed JSON
function fireFormRevenueEvent() {
var eventName = document.getElementById('eventName').value;
var currency = document.getElementById('currency').value;
var amount = document.getElementById('amount').value;
var attributesRaw = document.getElementById('attributes').value;
var attributes = null;
if (attributesRaw) {
try {
// Try to parse the optional attributes field from JSON string
attributes = JSON.parse(attributesRaw);
} catch (e) {
alert("Optional attributes must be valid JSON.");
return; // Stop if invalid JSON
}
}
// Calls main revenue logic for deduplication and event sending
sendRevenueEvent(eventName, amount, currency, attributes);
}
// Controls which form fields are visible depending on selected event type
// Revenue events require currency, amount, and attributes fields
function handleRevenueFields(sender) {
var isRevenue = sender.value === "revenue";
document.getElementById("currencyGroup").style.display = isRevenue ? "block" : "none";
document.getElementById("amountGroup").style.display = isRevenue ? "block" : "none";
document.getElementById("attributesGroup").style.display = isRevenue ? "block" : "none";
// Dynamically assign the event button's onclick handler
var send = document.getElementById("send");
send.onclick = (sender.value === "custom") ? sendCustomEvent
: (sender.value === "conversion") ? sendConversionEvent
: fireFormRevenueEvent; // Only fires revenue logic for "revenue"
}
// Opens demo Singular web-to-app link in a new tab/window
function testWebLink() {
var singularWebToAppBaseLink = 'https://seteam.sng.link/D0mvs/y3br?_smtype=3';
window.open(singularWebToAppBaseLink);
}
// Displays constructed Singular web-to-app link with campaign parameters
function displayWebLink() {
var singularWebToAppBaseLink = 'https://seteam.sng.link/D0mvs/y3br?_smtype=3';
var builtLink = window.singularSdk.buildWebToAppLink(singularWebToAppBaseLink);
console.log("Singular Web-to-App Link: ", builtLink);
alert("Singular Web-to-App Link: " + builtLink);
}
// Generates QR code for desktop deep linking using Singular Mobile Web-to-App link
function generateDesktopWebToAppQRCode() {
var singularWebToAppBaseLink = 'https://seteam.sng.link/D0mvs/y3br?_smtype=3';
const value = window.singularSdk.buildWebToAppLink(singularWebToAppBaseLink);
new QRCode(document.getElementById("qrcode"), {
text: value,
width: 128,
height: 128,
colorDark: "#000",
colorLight: "#fff",
correctLevel: QRCode.CorrectLevel.H
});
}
// Simulate user authentication and send login event
function setUserId() {
var userId = document.getElementById('userId').value;
window.singularSdk.login(userId);
console.log("Singular User ID is Set to: " + userId);
window.singularSdk.event("sng_login");
}
// Simulate user logout and unset Singular user ID
function unsetUserId() {
window.singularSdk.logout();
console.log("Singular User ID is Unset");
}
</script>
</body>
</html>
Tópicos avançados
Banners Singular
INFORMAÇÃO: Banners singulares é um recurso empresarial . Para saber mais sobre esse recurso, entre em contato com seu Gerente de Sucesso do Cliente.
Os banners singulares podem ser exibidos em seu site móvel para direcionar os usuários da web de forma integrada ao seu aplicativo e exibir o conteúdo mais relevante do aplicativo. Depois de ativar os banners singulares em seu site, sua organização poderá facilmente criar, implantar e manter banners por meio da interface do usuário dos banners singulares.
Artigos relacionados
Guia de implementação passo a passo
-
Adicione o script Singular Native JavaScript WebSDK ao seu site.
-
Conceda permissão ao Singular para acessar dados de dicas do cliente
Com as limitações nos dados do agente do usuário em navegadores baseados em Chromium , implementadas em fevereiro-março de 2023, os anunciantes agora precisam obter dados de dicas do cliente, bem como conceder ao Singular WebSDK permissão para receber esses dados. Para mais informações, consulte as Perguntas frequentes sobre banners.
O site precisa:
-
Começar a solicitar dicas do cliente (
accept-ch header). -
Conceder permissão ao Singular (como terceiro) para que
o
navegador envie ao Singular as dicas do cliente nas
solicitações de banner
(
permissions-policy header).
Adicionar os seguintes cabeçalhos de resposta à resposta de carregamento da página:
accept-ch: sec-ch-ua-model, sec-ch-ua-platform-version, sec-ch-ua-full-version-list permissions-policy: ch-ua-model=("https://sdk-api-v1.singular.net"), ch-ua-platform-version=("https://sdk-api-v1.singular.net"), ch-ua-full-version-list=("https://sdk-api-v1.singular.net") -
Começar a solicitar dicas do cliente (
-
Adicionar a opção de configuração de banner à inicialização do WebSDK
Os banners Singular exibem prompts inteligentes de download de aplicativos em seu site móvel, preservando a atribuição da fonte de marketing original. Quando habilitado com suporte web-to-app, o SDK rastreia qual rede de anúncios ou campanha trouxe o usuário ao seu site e, em seguida, atribui a instalação subsequente do aplicativo de volta à fonte original.
/** * Initialize Singular SDK with Banner support and web-to-app attribution. * This enables smart banners that direct mobile web users to download your app * while preserving the original marketing source (UTM parameters, ad network, etc.) * for proper attribution when the app is installed. * @param {string} sdkKey - Your Singular SDK Key * @param {string} sdkSecret - Your Singular SDK Secret * @param {string} productId - Your Product ID (e.g., com.your-website) */ function initSingularSDK() { // Enable web-to-app tracking to preserve attribution data var bannersOptions = new BannersOptions().withWebToAppSupport(); // Configure SDK with banner support var config = new SingularConfig(sdkKey, sdkSecret, productId) .withBannersSupport(bannersOptions); // Initialize the SDK window.singularSdk.init(config); // Display the smart banner window.singularSdk.showBanner(); } // Call on DOM ready document.addEventListener('DOMContentLoaded', function() { initSingularSDK(); }); -
Exibir novamente o banner na rota da página (apenas aplicativos de página única)
Se o seu aplicativo for um aplicativo de página única, você terá que ocultar e exibir novamente o banner em cada rota de página. Isso garante que o Singular entregue o banner apropriado para a sua experiência na web.
Para ocultar e exibir novamente o banner, use o seguinte código:
window.singularSdk.hideBanner(); window.singularSdk.showBanner(); -
[Opção avançada] Personalizar configurações de link
O Singular oferece uma maneira de personalizar os links no banner por meio de código.
Para personalizar links:
-
Crie um objeto
LinkParamse use uma ou mais das funções abaixo. Faça isso antes de chamarwindow.singularSdk.showBanner(). -
Em seguida, passe o objeto
LinkParamsquando você chamarwindow.singularSdk.showBanner().
Exemplo:
// Define a LinkParams object let bannerParams = new LinkParams(); // Configure link options (see details on each option below) bannerParams.withAndroidRedirect("androidRedirectValue"); bannerParams.withAndroidDL("androidDLParamValue"); bannerParams.withAndroidDDL("androidDDLparamValue"); bannerParams.withIosRedirect("iosRedirectValue"); bannerParams.withIosDL("iosDLValue"); bannerParams.withIosDDL("iosDDLValue"); // Show the banner with the defined options window.singularSdk.showBanner(bannerParams);Lista de opções:
Método Descrição withAndroidRedirectPasse um link de redirecionamento para a página de download do seu aplicativo Android , geralmente uma página da Play Store. withAndroidDLPasse um link direto para uma página dentro do seu aplicativo Android. withAndroidDDLPasse um link direto diferido, ou seja, um link para uma página no seu aplicativo Android que o usuário ainda não instalou . withIosRedirectPasse um link de redirecionamento para a página de download do seu aplicativo iOS , geralmente uma página da App Store. withIosDLPasse um link direto para uma página dentro do seu aplicativo iOS. withIosDDLPasse um link direto diferido, ou seja, um link para uma página no seu aplicativo iOS que o usuário ainda não instalou . -
Crie um objeto
-
[Opção avançada] Use código para forçar a ocultação/exibição de banners
Conforme mencionado na etapa 3, se você tiver um aplicativo de página única, deve usar os métodos
hideBanner()eshowBanner()em cada rota de página para garantir que o banner apropriado seja exibido (veja acima).hideBanner()eshowBanner()também estão disponíveis para você usar em todo o seu código se quiser ocultar um banner que seria exibido ou exibir novamente um banner que você ocultou.Método Descrição singularSdk.hideBanner()Ocultar um banner visível da sua página. singularSdk.showBanner()Mostra o banner pré-configurado. singularSdk.showBanner(params)Mostrar o banner pré-configurado, mas substituir links pelas opções definidas no objeto linkParams ( veja a etapa 4).
Propriedades globais
O SDK Singular permite definir propriedades personalizadas a serem enviadas aos servidores Singular junto com cada sessão e evento enviado pelo aplicativo. Essas propriedades podem representar qualquer informação que você desejar sobre o usuário, o modo/status do aplicativo ou qualquer outra coisa.
-
Você pode definir até 5 propriedades globais como um objeto JSON válido. As propriedades globais são mantidas nos navegadores
localstorageaté serem apagadas ou o contexto do navegador ser alterado. -
Cada nome e valor de propriedade pode ter até 200 caracteres. Se você passar um nome ou valor de propriedade mais longo, ele será truncado para 200 caracteres.
-
As propriedades globais são atualmente refletidas nos logs de eventos no nível do usuário do Singular (consulte Exportando logs de atribuição) e nos postbacks.
-
As propriedades globais estão disponíveis para mim enviadas em postbacks do Singular para terceiros para fins de correspondência, se necessário.
Para oferecer suporte à configuração de propriedades globais durante a inicialização do WebSDK,
você deve implementar a opção .withGlobalProperties()
no objeto de configuração.
Para lidar com propriedades globais após a inicialização, você deve usar
as funções SDK: setGlobalProperties(),
getGlobalProperties() ,
clearGlobalProperties() .
/**
* Set a Singular global property during SDK initialization.
* Allows up to 5 key/value pairs. Optionally overwrites existing value for a key.
* @param {{[key: string]: string}} globalProperties - The global property key/value pair object.
* @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.
*/
// Global Properties set during init (plain object; max 5 keys persisted).
var globalProperties = {
propertyKey: propertyValue
};
// Set the override, applies to the whole object: false = merge with existing, true = clear existing then set.
var overrideExisting = false; // required
var config = new SingularConfig(sdkKey, sdkSecret, productId)
.withLogLevel(3)
.withSessionTimeoutInMinutes(0.5)
.withGlobalProperties(globalProperties, overrideExisting)
.withInitFinishedCallback(function (initParams) {
console.log("Singular Device ID:", initParams.singularDeviceId);
console.log("Global props (SDK):", window.singularSdk.getGlobalProperties());
// If you need to override just one key after init set it in the withInitFinishedCallback:
window.singularSdk.setGlobalProperties("plan", "enterprise");
});
// Initialize the Singular SDK
window.singularSdk.init(config);
/**
* Define uma propriedade global Singular após a inicialização do SDK.
* Permite até 5 pares de chave/valor. Opcionalmente, sobrescreve o valor existente para uma chave.
*
* @param {string} propertyKey - A chave da propriedade a ser definida.
* @param {string} propertyValue - O valor da propriedade a ser definido.
* @param {boolean} overrideExisting - Se a propriedade já existe, se deve ser substituída.
*/
// Utilização
window.singularSdk.setGlobalProperties(propertyKey, propertyValue, overrideExisting);
// Get the JSON Object of global property values.
// Usage
window.singularSdk.getGlobalProperties();
// Clears all global property values.
// Usage
window.singularSdk.clearGlobalProperties();
Rastreamento entre subdomínios
Por padrão, o Singular WebSDK gera um Singular Device ID e o mantém usando o armazenamento do navegador. Como esse armazenamento não pode ser compartilhado entre subdomínios, o SDK acaba gerando um novo ID para cada subdomínio.
Se você deseja manter o ID do dispositivo Singular entre subdomínios, pode usar uma das seguintes opções:
Método A: Persistência automática usando cookies
Você pode fazer com que o SDK Singular mantenha o ID do dispositivo Singular usando um cookie personalizado de primeira parte . Use o método a seguir e defina o domínio principal que deseja rastrear.
| com o método AutoPersistentSingularDeviceId | |
|---|---|
| Descrição | Inicialize o SDK com opções de configuração, incluindo o domínio principal para persistência automática do Singular Device Id. |
| Assinatura | withAutoPersistentSingularDeviceId(domain) |
| Exemplo de uso |
|
Método B (avançado): definir manualmente o ID do dispositivo Singular
Se você não quiser que o SDK Singular persista o ID do dispositivo automaticamente, você pode persistir o ID manualmente entre domínios - por exemplo, usando um cookie de domínio de nível superior ou um cookie do lado do servidor. O valor deve ser um ID previamente gerado pelo Singular, no formato uuid4 válido.
NOTA: Você pode ler o ID do dispositivo Singular usando singularSdk.getSingularDeviceId() após chamar o método init ou usar InitFinishedCallback.
| Método withPersistentSingularDeviceId | |
|---|---|
|
Descrição |
Inicialize o SDK com opções de configuração, incluindo o Singular Device Id que você deseja manter. |
| Assinatura | withPersistentSingularDeviceId(singularDeviceId) |
| Exemplo de uso |
|
Próximos passos
- Crie links de sites no Singular para suas campanhas na web
- Siga nossos guias para Google Ads Web, Facebook Web e TikTok Ads Web, se você executar campanhas na web para inventário móvel.
- Monitore seus dados nos relatórios do Singular