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

# Nuxt

> Monte o widget num app Nuxt 3, com o script carregado pelo head e a credencial vinda do servidor.

Ao final deste guia o fluxo de verificação abre num app Nuxt 3, com o componente montando só no
cliente e a credencial emitida por uma rota de servidor.

## 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">
    Declare o script no `nuxt.config.ts`. Ele entra no `<head>` de todas as páginas e registra
    `window.Legitimuz` antes do bundle.

    ```ts title="nuxt.config.ts" theme={null}
    export default defineNuxtConfig({
      app: {
        head: {
          script: [{ src: "https://sdk.legitimuz.com/v1/websdk.js" }],
        },
      },
    });
    ```
  </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 composable">
    ```ts title="composables/useLegitimuz.ts" theme={null}
    import type { LegitimuzWidgetHandle, MountOptions } from "~/types/legitimuz";

    export type UseLegitimuzOptions = Omit<MountOptions, "target">;

    export function useLegitimuz(options: UseLegitimuzOptions) {
      const containerRef = ref<HTMLDivElement | null>(null);
      let handle: LegitimuzWidgetHandle | null = null;

      onMounted(() => {
        if (!containerRef.value) return;
        handle = window.Legitimuz.mount({ ...options, target: containerRef.value });
      });

      onUnmounted(() => handle?.destroy());

      return containerRef;
    }
    ```
  </Step>

  <Step title="Emita a credencial numa rota de servidor">
    ```ts title="server/api/verificacoes.post.ts" theme={null}
    export default defineEventHandler(async (event) => {
      const usuario = await autenticar(event);
      const cadastro = await db.cadastro.porUsuario(usuario.id);

      const resposta = await $fetch<{ verification: { public_id: string }; entry: { url: string } }>(
        "https://api.legitimuz.com/public/verifications",
        {
          method: "POST",
          headers: { "X-API-Key": useRuntimeConfig().legitimuzApiKey },
          body: {
            schema_version: "1.0",
            ref_id: cadastro.id,
            document: { type: "cpf", number: cadastro.cpf },
            integration_origin_public_id: useRuntimeConfig().legitimuzOriginId,
          },
        }
      );

      await db.cadastro.vincular(cadastro.id, resposta.verification.public_id);
      return { entry: resposta.entry };
    });
    ```

    A chave fica em `runtimeConfig`, que só existe no servidor.
  </Step>

  <Step title="Use na página">
    ```vue title="pages/verificacao.vue" theme={null}
    <script setup lang="ts">
    const { data } = await useFetch("/api/verificacoes", { method: "POST" });

    const log = ref<string[]>([]);
    const containerRef = useLegitimuz({
      sdkUrl: data.value!.entry.url,
      onReady: () => log.value.push("ready"),
      onEvent: (event) => log.value.push(`event: ${event.type}`),
      // "o fluxo terminou", não "deu certo". O desfecho chega pelo webhook.
      onComplete: (result) => log.value.push(`complete: ${result.status}`),
    });
    </script>

    <template>
      <ClientOnly>
        <div ref="containerRef" style="height: 640px"></div>
        <pre>{{ log.join("\n") }}</pre>
      </ClientOnly>
    </template>
    ```
  </Step>
</Steps>

## Confira que funcionou

A primeira tela aparece dentro do container e o `<pre>` recebe `ready`. No console do servidor não
há referência a `window`.

## Boas práticas

<Card title="ClientOnly em volta do container" icon="checklist" horizontal>
  O widget usa `window` e a câmera, que só existem no browser. `<ClientOnly>` garante que o
  container renderize apenas no cliente, e o `onMounted` do composable encontra `window.Legitimuz`
  pronto.
</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="player-play" href="/guides/first-verification">
    Rode a jornada ponta a ponta e veja a decisão chegar.
  </Card>
</Columns>
