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

# Remix

> Monte o widget num app Remix ou React Router 7, com a credencial emitida por uma action de servidor.

Ao final deste guia o fluxo de verificação abre num app Remix, com a credencial vinda de uma
`action` de servidor e o widget montando no cliente.

## 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 `root.tsx`, antes dos scripts do app.

    ```tsx title="app/root.tsx" theme={null}
    import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";

    export default function Root() {
      return (
        <html lang="pt-BR">
          <head>
            <Meta />
            <Links />
            <script src="https://sdk.legitimuz.com/v1/websdk.js" />
          </head>
          <body>
            <Outlet />
            <ScrollRestoration />
            <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 no loader">
    ```tsx title="app/routes/verificacao.tsx" theme={null}
    import { useLoaderData } from "react-router";
    import { useLegitimuz } from "~/hooks/useLegitimuz";

    export async function loader({ request }: { request: Request }) {
      const usuario = await autenticar(request);
      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 };
    }

    export default function Verificacao() {
      const { sdkUrl } = useLoaderData<typeof loader>();
      const { containerRef, status } = useLegitimuz({ sdkUrl });

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

    O `loader` roda só no servidor. A chave nunca chega ao bundle do cliente.

    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` entrega só a `sdkUrl` ao componente. O `useEffect` do hook roda no browser, onde
  `window.Legitimuz` já existe porque o script está no `root.tsx`.
</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>
