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

# Debugging

> Guia completo para identificar e resolver problemas com o Testly SDK

## Debug Mode

A primeira ferramenta para troubleshooting é ativar o modo debug.

```tsx theme={null}
<TestlyProvider 
  apiKey="tk_live_..."
  config={{ debug: true }}
>
```

Com `debug: true` você verá logs como:

```
[Testly] ✅ Conversion recorded for homepage-hero-test
[Testly] ❌ API ERROR: Failed to track impression. Status: 401
[Testly] ❌ TRACKING BLOCKED: Missing critical IDs for experiment "my-test"
```

<Tip>
  Sempre desenvolva com `debug: true`. Desative em produção para não poluir o console dos usuários.
</Tip>

***

## Problemas Comuns

### 1. `variant` retorna `null` — causa mais comum

**Sintoma:**

```tsx theme={null}
const { variant } = useExperiment('meu-experimento');
console.log(variant); // null
```

A causa número 1 é **mismatch entre a API Key e a organização onde o experimento foi criado**.

O SDK envia sua API Key para o servidor, que busca o experimento dentro daquela organização. Se você usar a key de uma conta diferente, o servidor não encontra o experimento e retorna `null`.

**Checklist:**

<AccordionGroup>
  <Accordion title="API Key pertence à organização errada" icon="key">
    **Como verificar:**

    1. Abra [app.testly.com.br/settings](https://app.testly.com.br/settings) → copie a API Key (`tk_live_...`)
    2. Confirme que **exatamente essa key** está no `TestlyProvider` do seu app
    3. Confirme que o experimento está listado no dashboard da mesma conta

    Ative o debug e inspecione a resposta do servidor:

    ```tsx theme={null}
    <TestlyProvider apiKey="..." config={{ debug: true }}>
    ```
  </Accordion>

  <Accordion title="Slug do experimento está errado" icon="flask">
    O slug (identificador) usado em `useExperiment()` deve ser **idêntico** ao slug exibido no dashboard — case-sensitive, apenas letras minúsculas e hífens.

    ```tsx theme={null}
    // ✅ Correto — exatamente como aparece no dashboard
    useExperiment('homepage-hero-test')

    // ❌ Errado
    useExperiment('homepage-hero')        // slug diferente
    useExperiment('Homepage-Hero-Test')   // case errado
    useExperiment('homepage_hero_test')   // underscore em vez de hífen
    ```
  </Accordion>

  <Accordion title="Experimento não está em estado running" icon="circle-pause">
    O servidor só retorna variante para experimentos com status **running**. Se o experimento foi pausado, concluído ou arquivado, o retorno é `null`.

    **Solução:** Verifique o status no dashboard e ative o experimento se necessário.
  </Accordion>

  <Accordion title="TestlyProvider não está envolvendo o componente" icon="layer-group">
    ```tsx theme={null}
    // ✅ Correto
    <TestlyProvider apiKey="...">
      <App>
        <MeuComponente /> {/* pode usar useExperiment */}
      </App>
    </TestlyProvider>

    // ❌ Errado
    <App>
      <MeuComponente /> {/* NÃO pode usar useExperiment */}
      <TestlyProvider apiKey="...">...</TestlyProvider>
    </App>
    ```
  </Accordion>
</AccordionGroup>

***

### 2. Loading nunca termina

**Sintoma:**

```tsx theme={null}
const { loading } = useExperiment('test');
console.log(loading); // sempre true
```

**Diagnóstico:**

```tsx theme={null}
const { variant, loading, error } = useExperiment('test');

useEffect(() => {
  console.log('variant:', variant, '| loading:', loading, '| error:', error);
}, [variant, loading, error]);
```

**Causas e soluções:**

<AccordionGroup>
  <Accordion title="Erro de rede" icon="wifi">
    Abra DevTools → Network → Procure por chamadas para `supabase.co/functions/v1/get-variant`.

    Possíveis problemas:

    * Request bloqueado por CORS ou firewall
    * Timeout (resposta muito lenta)

    Se a request estiver falhando, verifique o erro em `error` e entre em contato: [suporte@testly.com.br](mailto:suporte@testly.com.br)
  </Accordion>

  <Accordion title="API Key inválida — formato errado" icon="key">
    A API Key deve ter o formato `tk_live_...`. Se estiver em formato diferente ou vazia, o servidor rejeita a request antes de responder.

    ```tsx theme={null}
    // ✅ Formato correto
    apiKey="tk_live_abc123..."

    // ❌ Formatos errados
    apiKey=""
    apiKey="undefined"
    apiKey={process.env.TESTLY_API_KEY} // sem prefixo VITE_ ou NEXT_PUBLIC_
    ```
  </Accordion>
</AccordionGroup>

***

### 3. Conversões não são registradas

**Sintoma:** `convert()` é chamado mas o dashboard não mostra os dados.

**Diagnóstico:**

```tsx theme={null}
const { convert } = useExperiment('test');

const handleClick = async () => {
  try {
    await convert('cta_clicked');
    console.log('✅ Conversão registrada!');
  } catch (err) {
    console.error('❌ Erro:', err);
  }
};
```

**Causas:**

<AccordionGroup>
  <Accordion title="Deduplicação ativa" icon="copy">
    Por padrão, o SDK deduplicata conversões: a mesma conversão para o mesmo experimento só é registrada uma vez por sessão.

    ```tsx theme={null}
    convert('cta_clicked'); // ✅ Registrada
    convert('cta_clicked'); // ❌ Ignorada (dedupe)
    ```

    Para testar sem dedupe, limpe o localStorage e recarregue a página, ou desative temporariamente:

    ```tsx theme={null}
    <TestlyProvider config={{ dedupConversions: false }}>
    ```
  </Accordion>

  <Accordion title="Nome do evento inválido" icon="tag">
    ```tsx theme={null}
    // ✅ Bom — snake_case, descritivo
    convert('cta_clicked')
    convert('form_submitted')
    convert('trial_started')

    // ❌ Ruim
    convert('')                           // vazio
    convert('Botão Clicado!!!')           // caracteres especiais
    ```
  </Accordion>

  <Accordion title="Impressão não foi registrada primeiro" icon="eye">
    Conversões só são contabilizadas se o usuário teve uma impressão registrada antes. A impressão é automática — mas ocorre apenas quando `loading` termina.

    Certifique-se de que o componente está renderizando o `useExperiment` antes de chamar `convert`:

    ```tsx theme={null}
    const { variant, loading, convert } = useExperiment('test');

    if (loading) return <Skeleton />;
    // Aqui loading=false, impressão já foi registrada

    return <button onClick={() => convert('clicked')}>...</button>;
    ```
  </Accordion>
</AccordionGroup>

***

### 4. Variante muda a cada refresh

**Isso não deveria acontecer.** O SDK usa cache local para manter consistência.

<AccordionGroup>
  <Accordion title="localStorage sendo limpo" icon="trash">
    Procure no seu código por:

    ```tsx theme={null}
    localStorage.clear(); // ❌ Remove cache do Testly
    ```

    Se precisar limpar seu próprio storage, remova chaves específicas:

    ```tsx theme={null}
    localStorage.removeItem('minha-chave'); // ✅ Específico
    ```
  </Accordion>

  <Accordion title="Navegação privada/anônima" icon="user-secret">
    Em modo anônimo, o storage é limpo ao fechar a aba. Isso é esperado. Para testar consistência, use navegação normal.
  </Accordion>

  <Accordion title="userId customizado instável" icon="user">
    ```tsx theme={null}
    // ❌ Ruim — userId muda a cada render
    const { variant } = useExperiment('test', {
      userId: Math.random().toString()
    });

    // ✅ Bom — userId estável
    const { variant } = useExperiment('test', {
      userId: user?.id || 'anonymous'
    });
    ```
  </Accordion>
</AccordionGroup>

***

### 5. Erro: "useExperiment must be used within TestlyProvider"

```tsx theme={null}
// ❌ Errado — hook fora do Provider
function App() {
  const { variant } = useExperiment('test'); // Erro!
  return (
    <TestlyProvider apiKey="...">
      <Component />
    </TestlyProvider>
  );
}

// ✅ Correto — hook dentro do Provider
function App() {
  return (
    <TestlyProvider apiKey="...">
      <Component />
    </TestlyProvider>
  );
}

function Component() {
  const { variant } = useExperiment('test'); // OK
  return <div>{variant}</div>;
}
```

***

### 6. TypeScript: Tipos não reconhecidos

```
Cannot find module '@testlyjs/react' or its corresponding type declarations
```

**Soluções:**

<AccordionGroup>
  <Accordion title="Reinstalar pacote" icon="download">
    ```bash theme={null}
    rm -rf node_modules package-lock.json
    npm install
    ```
  </Accordion>

  <Accordion title="Verificar tsconfig.json" icon="gear">
    ```json tsconfig.json theme={null}
    {
      "compilerOptions": {
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": true
      }
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Verificar Requests no DevTools

Abra DevTools → Network e procure por chamadas para `supabase.co/functions/v1/`.

**`get-variant`** — atribuição de variante:

```
GET .../functions/v1/get-variant?experiment_key=...&user_id=...&apikey=tk_live_...

Resposta esperada:
{ "variant_key": "control", "variant_id": "...", "experiment_id": "..." }

Resposta quando algo está errado:
{ "variant_key": null, "reason": "experiment_not_running" }  → API key ou org errada
{ "error": "Invalid API Key" }                                → key inválida
```

**`track-event`** — impressões e conversões:

```
POST .../functions/v1/track-event

Resposta esperada: { "success": true }
```

***

## Casos Especiais

### Next.js: Hydration Mismatch

**Sintoma:**

```
Warning: Text content did not match. Server: "control" Client: "variant-b"
```

**Solução:**

```tsx theme={null}
'use client';

function MeuComponente() {
  const { variant, loading } = useExperiment('test');
  const [mounted, setMounted] = useState(false);

  useEffect(() => { setMounted(true); }, []);

  if (!mounted || loading) return <Skeleton />;

  return <div>{variant}</div>;
}
```

### React Strict Mode (Logs duplicados)

Em desenvolvimento com Strict Mode, componentes renderizam duas vezes — logs `[Testly]` podem aparecer duplicados. Isso é esperado e não afeta produção.

***

## Checklist de Troubleshooting

<Steps>
  <Step title="Ativar debug mode">
    `config={{ debug: true }}` e recarregar a página
  </Step>

  <Step title="Verificar console">
    Procure por erros vermelhos ou logs `[Testly]`
  </Step>

  <Step title="Verificar Network tab">
    Há requests para `supabase.co/functions/v1/get-variant`? Qual a resposta?
  </Step>

  <Step title="Verificar API Key">
    A key no `TestlyProvider` é a mesma que está em Settings → API Key?
  </Step>

  <Step title="Verificar o experimento">
    Está em status **running** no dashboard? O slug é idêntico?
  </Step>

  <Step title="Limpar cache">
    ```javascript theme={null}
    localStorage.clear(); location.reload();
    ```
  </Step>

  <Step title="Testar em aba anônima">
    Elimina problemas de cache e extensões do browser
  </Step>
</Steps>

***

## Precisa de Ajuda?

<CardGroup cols={2}>
  <Card title="Email" icon="envelope" href="mailto:suporte@testly.com.br">
    [suporte@testly.com.br](mailto:suporte@testly.com.br) — respondemos rápido
  </Card>

  <Card title="Documentação" icon="book" href="/quickstart">
    Guia rápido de 5 minutos
  </Card>
</CardGroup>

**Ao pedir ajuda, inclua:**

* Versão do SDK (`npm list @testlyjs/react`)
* Framework (Next.js, Vite, etc.)
* Logs do debug mode
* Screenshot do Network tab
* Código relevante (remova a API Key!)
