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

# TanStack Start

> Monte o widget num app TanStack Start, com a credencial emitida por uma server function.

Ao final deste guia o fluxo de verificação abre num app TanStack Start, com o componente montando no
cliente e a credencial vindo de uma server function.

## 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 `head` da rota raiz. Ele registra `window.Legitimuz` antes do bundle.

    ```tsx title="src/routes/__root.tsx" theme={null}
    import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router";

    export const Route = createRootRoute({
      head: () => ({
        scripts: [{ src: "https://sdk.legitimuz.com/v1/websdk.js" }],
      }),
      component: () => (
        <html>
          <head>
            <HeadContent />
          </head>
          <body>
            <Outlet />
            <Scripts />
          </body>
        </html>
      ),
    });
    ```
  </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="Emita a credencial numa server function">
    ```ts title="src/server/criar-verificacao.ts" theme={null}
    import { createServerFn } from "@tanstack/react-start";

    export const criarVerificacao = createServerFn({ method: "POST" }).handler(async () => {
      const usuario = await autenticar();
      const cadastro = await db.cadastro.porUsuario(usuario.id);

      const resposta = await fetch("https://api.legitimuz.com/public/verifications", {
        method: "POST",
        headers: {
          "X-API-Key": process.env.LEGITIMUZ_API_KEY!,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          schema_version: "1.0",
          ref_id: cadastro.id,
          document: { type: "cpf", number: cadastro.cpf },
          integration_origin_public_id: process.env.LEGITIMUZ_ORIGIN_ID!,
        }),
      });

      const { verification, entry } = await resposta.json();
      await db.cadastro.vincular(cadastro.id, verification.public_id);
      return { sdkUrl: entry.url as string };
    });
    ```

    Server functions rodam só no servidor. A chave nunca chega ao bundle do cliente.
  </Step>

  <Step title="Use na rota">
    ```tsx title="src/routes/verificacao.tsx" theme={null}
    import { createFileRoute } from "@tanstack/react-router";
    import { useLegitimuz } from "../hooks/useLegitimuz";
    import { criarVerificacao } from "../server/criar-verificacao";

    export const Route = createFileRoute("/verificacao")({
      loader: () => criarVerificacao(),
      component: Verificacao,
    });

    function Verificacao() {
      const { sdkUrl } = Route.useLoaderData();
      const { containerRef, status } = useLegitimuz({ sdkUrl });

      return (
        <>
          <div ref={containerRef} style={{ height: 640 }} />
          <p>{status}</p>
        </>
      );
    }
    ```

    O hook `useLegitimuz` é o mesmo do [guia de React](/guides/web/react): monta uma vez por
    `sdkUrl` e chama `destroy()` no cleanup.
  </Step>
</Steps>

## Confira que funcionou

A primeira tela aparece dentro do container e o `status` vira `pronto`.

## Boas práticas

<Card title="Loader no servidor, montagem no cliente" icon="checklist" horizontal>
  O `loader` chama a server function e entrega só a `sdkUrl` ao componente. O `useEffect` do hook
  roda no browser, onde `window.Legitimuz` já existe.
</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>
