> ## 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.

# Svelte

> Monte o widget num app Svelte ou SvelteKit, com o ciclo de vida preso ao componente.

Ao final deste guia o fluxo de verificação abre num app Svelte 5, montando quando o componente
entra na tela e encerrando quando ele sai.

## Pré-requisitos

* Node.js 20 ou superior.
* Uma `sdkUrl` emitida pelo seu backend, como em [emitir a credencial](/guides/credential).

## Monte o fluxo

<Steps>
  <Step title="Carregue o SDK">
    No SvelteKit, o script entra no `app.html`. Em Svelte puro, no `index.html`.

    ```html title="src/app.html" theme={null}
    <script src="https://sdk.legitimuz.com/v1/websdk.js"></script>
    ```

    Antes do bundle. O script registra `window.Legitimuz`.
  </Step>

  <Step title="Declare o global">
    O build de CDN não traz tipos. Reaproveite a declaração do
    [guia de React](/guides/web/react); ela é a mesma.
  </Step>

  <Step title="Escreva o componente">
    ```svelte title="src/lib/VerificationWidget.svelte" theme={null}
    <script lang="ts">
      import { onMount } from "svelte";
      import type { LegitimuzWidgetHandle, WebSdkEvent } from "$lib/legitimuz";

      let { sdkUrl }: { sdkUrl: string } = $props();

      let container: HTMLDivElement;
      let log = $state<string[]>([]);

      onMount(() => {
        const handle: LegitimuzWidgetHandle = window.Legitimuz.mount({
          sdkUrl,
          target: container,
          onReady: () => log.push("ready"),
          onEvent: (event: WebSdkEvent) => log.push(`event: ${event.type}`),
          // "o fluxo terminou", não "deu certo". O desfecho chega pelo webhook.
          onComplete: (result) => log.push(`complete: ${result.status}`),
          onError: (error) => log.push(`error ${error.code}`),
        });

        return () => handle.destroy();
      });
    </script>

    <div bind:this={container} style="height: 640px"></div>
    <pre>{log.join("\n")}</pre>
    ```

    O retorno do `onMount` roda no desmonte e chama `destroy()`, que encerra a câmera.
  </Step>

  <Step title="Passe a sdkUrl pela rota">
    No SvelteKit, a credencial vem do servidor pelo `load`. Assim ela nunca fica no bundle.

    ```ts title="src/routes/verificacao/+page.server.ts" theme={null}
    import type { PageServerLoad } from "./$types";

    export const load: PageServerLoad = async ({ fetch }) => {
      const resposta = await fetch("/api/verificacoes", { method: "POST" });
      const { entry } = await resposta.json();
      return { sdkUrl: entry.url };
    };
    ```

    ```svelte title="src/routes/verificacao/+page.svelte" theme={null}
    <script lang="ts">
      import VerificationWidget from "$lib/VerificationWidget.svelte";
      let { data } = $props();
    </script>

    <VerificationWidget sdkUrl={data.sdkUrl} />
    ```
  </Step>
</Steps>

## Confira que funcionou

A primeira tela aparece dentro do container e o `<pre>` recebe `ready`. Ao navegar para outra rota,
o indicador de câmera do browser apaga.

## Boas práticas

<Card title="Monte no cliente, emita no servidor" icon="checklist" horizontal>
  `onMount` só roda no browser, então `window.Legitimuz` está disponível quando o componente monta.
  A `sdkUrl` vem do `load` do servidor, e a chave de API fica só lá.
</Card>

## Próximo passo

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

  <Card title="Testar" icon="play" href="/guides/first-verification">
    Rode a jornada ponta a ponta e veja a decisão chegar.
  </Card>
</Columns>
