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

# Vanilla JS

> Monte o widget de verificação com uma tag script e nada mais: sem npm, sem bundler, sem build.

Ao final deste guia o fluxo de verificação abre numa página HTML estática, sem passo de build.

Comece por aqui se é a sua primeira integração. Se o widget funciona aqui, funciona em qualquer
lugar onde um navegador rode — os outros guias existem para provar que um *framework* não atrapalha,
não para provar que o SDK funciona.

## Pré-requisitos

* Um navegador moderno.
* Uma `sdkUrl` emitida pelo seu backend, como no [passo 6](/setup/integrate). O SDK nunca gera uma
  sozinho.
* Um servidor HTTP local. Alguns navegadores bloqueiam a câmera em origem `file://`.

## Monte o fluxo

<Steps>
  <Step title="Crie a página">
    O widget renderiza dentro de um elemento seu e ocupa 100% da altura dele. Sem altura, ele existe
    na página e não aparece.

    ```html title="index.html" theme={null}
    <!doctype html>
    <html lang="pt-BR">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Verificação</title>
      </head>
      <body>
        <div id="kyc-widget" style="height: 640px"></div>
        <pre id="status"></pre>

        <script src="https://sdk.legitimuz.com/v1/websdk.js"></script>
        <script src="./verificacao.js"></script>
      </body>
    </html>
    ```

    A URL `v1` do CDN é evergreen: serve sempre a última versão sem breaking change. Não há o que
    importar, porque não há o que empacotar — o script registra `window.Legitimuz`.
  </Step>

  <Step title="Monte o widget">
    ```js title="verificacao.js" theme={null}
    // Vem do seu backend. Nunca chumbe uma sdkUrl real aqui: ela carrega a credencial da
    // verificação no fragmento da URL.
    const SDK_URL = "<SUA_SDK_URL>";

    const statusEl = document.getElementById("status");

    function log(text) {
      statusEl.textContent += `[${new Date().toISOString()}] ${text}\n`;
    }

    const handle = window.Legitimuz.mount({
      sdkUrl: SDK_URL,
      target: document.getElementById("kyc-widget"),
      onReady: () => log("ready"),
      onEvent: (event) => log(`event: ${event.type} ${JSON.stringify(event.payload ?? {})}`),
      // "o fluxo terminou", não "deu certo": status é "submitted" ou "abandoned"
      onComplete: (result) => log(`complete: ${result.status}`),
      onCancel: (result) => log(`cancelled: ${result.sessionId ?? "sem sessão"}`),
      // user_message pode ser mostrado ao titular; o resto é para o seu log
      onError: (error) => log(`error ${error.code}: ${error.user_message}`),
    });

    // encerra o iframe e a câmera ao sair da página
    window.addEventListener("pagehide", () => handle.destroy());
    ```
  </Step>

  <Step title="Sirva a página">
    ```bash theme={null}
    python3 -m http.server 8080
    ```

    Abra `http://localhost:8080`. Cadastre `localhost:8080` como origem autorizada da sua
    integração — é a única origem web que aceita porta. Veja o [passo 3](/setup/domains).
  </Step>
</Steps>

## Confira que funcionou

A primeira tela do fluxo aparece dentro do container e o `<pre>` recebe `ready`. A partir daí cada
etapa do titular chega como uma linha de `event`.

## O que este caminho prova

* O widget monta num `<div>` comum, com nada além de `window.Legitimuz.mount(...)`.
* Os cinco callbacks do contrato público disparam e carregam a forma documentada em
  [eventos](/web-sdk/events) e [tratamento de erros](/web-sdk/errors).
* `handle.destroy()` limpa o iframe e a stream de câmera junto.

## Próximo passo

<Columns cols={2}>
  <Card title="Opções do mount()" icon="settings-2" href="/web-sdk/options">
    Aparência, idioma, timeout e todos os callbacks.
  </Card>

  <Card title="7. Testar" icon="play" href="/setup/test">
    Rode a jornada ponta a ponta e veja a decisão chegar.
  </Card>
</Columns>
