> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xtracky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SPAs (Single Page Applications)

> Como o script V2 intercepta navegações client-side em React, Vue, Svelte, Next.js e outros.

Aplicações single-page trocam de "página" sem recarregar o HTML. Isso quebra scripts de tracking clássicos, que rodam apenas uma vez no primeiro load.

O script V2 (`experimental.js`) resolve isso interceptando duas APIs do navegador:

* **Navigation API** (`window.navigation.addEventListener('navigate', ...)`)
* **History API** (`pushState` / `replaceState` / `popstate`)

Sempre que o URL muda, o script re-avalia:

1. Precisa gerar novo `LeadId`? (se veio um novo `ttclid`/`fbclid`/etc. na URL)
2. Precisa disparar um novo step? (se `data-step-id` mudou)
3. Existe algum botão com `data-xtracky-checkout` na nova página?

## Nada a configurar

Se você usa React Router, Vue Router, SvelteKit, Next.js App Router, Nuxt ou qualquer outro roteador SPA, **basta incluir o script V2 uma única vez no HTML raiz**. Ele fica escutando o roteador do seu framework.

```html theme={null}
<!-- app.html / index.html raiz do SPA -->
<script src="https://cdn.xtracky.com/scripts/experimental.js"
  data-token="SEU_PRODUCT_ID"
  data-step-id="landing"
  async></script>
```

## Trocando o step ID em runtime

Se você quer que cada rota tenha um step diferente sem recarregar, atualize o atributo do script (ou emita um evento custom):

```javascript theme={null}
document.querySelector('script[data-token]')
  ?.setAttribute('data-step-id', 'checkout');
```

Ou, mais idiomático em SPAs, dispare um evento custom pra a xTracky:

```javascript theme={null}
window.dispatchEvent(new CustomEvent('xtracky:step', {
  detail: { stepId: 'checkout' }
}));
```

## Suporte a Suspense / SSR

O script é carregado com `async` e não bloqueia hidratação. Em Next.js/Nuxt/SvelteKit com SSR, funciona sem tocar em nada — ele só ativa depois do primeiro `DOMContentLoaded` no cliente.

<Warning>
  Não coloque o script dentro de um componente que pode ser desmontado. Coloque no HTML raiz (`_app.tsx`, `app.html`, `layout.tsx`, etc.). Se ele desmontar e remontar, você pode gerar `LeadId` duplicado.
</Warning>
