Pular para o conteúdo principal

App Mode (TWA + ?app=true)

A plataforma roda em 3 contextos distintos: web, PWA e App Android (TWA). O modo app tem comportamento de tracking radicalmente diferente do web — esta página explica por quê.

Os 3 contextos

ContextoComo detectarapp_sourceX-ORIGIN-ACCESS
Web DesktopUser-Agent não-mobile, sem ?app=true"web"2
Web MobileUser-Agent mobile, sem ?app=true"web"4
PWA StandalonematchMedia('(display-mode: standalone)')"pwa"2 ou 4
TWA App Android?app=true na URL inicial + window.twa bridge"app"1 ou 5

TWA — Trusted Web Activity

TWA é um APK Android que renderiza o site num WebView Chrome controlado. Comporta-se como app nativo (push, install, full screen, ícone na home), mas o conteúdo é o mesmo HTML/JS/CSS do site.

Identificação no front

URL inicial do TWA carrega ?app=true:

https://vera.bet.br/?app=true

Front lê esse param uma vez no boot e persiste. Subsequentes navegações herdam.

Bridge window.twa

APK injeta uma bridge JS:

window.twa = {
getPostMessageService: () => Promise<{
postMessage: (message: string) => void
}>
}

Front usa essa bridge pra:

  • Enviar eventos S2S pro AppsFlyer (via post message → APK encaminha)
  • Buscar device IDs (appsflyer_id, advertising_id, app_version)

Comportamento de tracking em modo app

Pixels client-side DESATIVADOS

shouldLoadTrackers = !isAppMode && !isBot

Quando isAppMode === true:

  • Meta Pixel: NÃO carrega
  • Kwai Pixel: NÃO carrega
  • Taboola: NÃO carrega
  • GTM: NÃO carrega
  • Clarity, Hotjar, Pendo, Webtrends: NÃO carregam

Razão

App tem requisitos diferentes:

  • Atribuição de install é via AppsFlyer S2S (não via pixel client)
  • WebView no APK tem comportamento sutilmente diferente de browser
  • Pixels client-side em app inflariam métricas de "web users" com tráfego mobile

O que continua funcionando em app

AppsFlyer S2S — único tracker ativo. Vai do BFF pro AppsFlyer.

cookie_tracking — UTMs ainda capturados (deeplink do APK pode trazer UTMs).

cookie_referrer — referrer ainda capturado (do APK).

rmkvera — UUID first-party gerado igual web.

Headers X-ORIGIN-* — todos viajam normalmente.

Smartico — gamification continua via SDK.

Detecção PWA

PWA é diferente de TWA:

  • PWA: site instalado via "Add to Home Screen" do browser (Chrome, Safari). Continua sendo browser, com permissões mais robustas.
  • TWA: APK próprio na Play Store. Browser é só engine de renderização.

Detection PWA via:

window.matchMedia('(display-mode: standalone)').matches

PWA não desativa pixels client-side (permanece em modo web normal). Apenas marca app_source: "pwa" no cookie_tracking.

Eventos especiais em modo app

APK pode lançar deeplink com UTMs:

https://vera.bet.br/?app=true&utm_source=appsflyer&utm_campaign=push_winback

Front captura UTMs normalmente + identifica como app + roteia AppsFlyer S2S em vez de pixel.

App version gating

versionGte(cookie_app_version, "2.5.0")

Permite gating de features por versão de APK. APK velho continua funcionando, novos recursos só ativam em APKs novos.

Configuração TWA por brand

BrandTWA package nameConfirmado no assetlinks.json
7kbr.bet.k.twasim (overrides/7k-bet-br/public/.well-known/)
Cassinocassino.bet.br.twasim
Verabr.bet.vera.twa.apksim
Demais brands(a confirmar com time mobile)

assetlinks.json é o Digital Asset Links do Google — prova que o domínio autoriza o APK a operar em modo TWA. Sem ele:

  • TWA perde modo url-bar-hidden
  • Smart Lock para na 1ª autenticação
  • Smartico push subscription quebra

Nunca alterar um caractere desse JSON. package_name + sha256_cert_fingerprints são chaves criptográficas atreladas ao APK no Play Store. Typo quebra TWA em prod até próximo deploy.

Como testar app mode

No browser (sem APK)

  1. Acesse http://localhost:5173/?app=true
  2. Console:
    // Simula bridge TWA
    window.twa = {
    getPostMessageService: async () => ({
    postMessage: (msg) => console.log("TWA bridge msg:", msg)
    })
    }
  3. Submeta deposit → Console deve logar mensagem TWA
  4. Network → Pixels (Meta, Kwai, etc) NÃO devem disparar

No APK real

Conecta dispositivo Android via USB → Chrome DevTools → chrome://inspect → seleciona WebView do APK.

Anti-patterns

  1. Disparar pixel client em modo app. Quebra atribuição mobile (apps inflate web metrics).
  2. Confiar em _fbp cookie em modo app. Não existe (Meta Pixel não carrega).
  3. Esquecer ?app=true no deeplink que o APK manda. Front roda como web e dispara pixels.
  4. Modificar assetlinks.json sem coordenar com time mobile. Quebra TWA em prod.
  5. Confundir PWA com TWA. PWA = browser instalado, pixels normais. TWA = APK próprio, pixels desativados.