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

# Next.js

> Monte o widget no App Router mantendo a página como Server Component e o SDK carregado a tempo.

Ao final deste guia o fluxo de verificação abre num app Next.js com App Router, com a página
permanecendo Server Component.

O App Router renderiza no servidor, onde `window` não existe. Duas coisas resolvem isso, e a segunda
é a que costuma passar despercebida.

## Pré-requisitos

* Node.js 20 ou superior.
* Uma `sdkUrl` emitida pelo seu backend, como em [emitir a credencial](/guides/credential).
* O [guia de React](/guides/web/react), o hook é o mesmo, e a declaração de tipos também.

## Monte o fluxo

<Steps>
  <Step title="Carregue o SDK no layout">
    ```tsx title="app/layout.tsx" theme={null}
    import Script from "next/script";

    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="pt-BR">
          <body>
            {children}
            <Script src="https://sdk.legitimuz.com/v1/websdk.js" strategy="beforeInteractive" />
          </body>
        </html>
      );
    }
    ```

    `beforeInteractive` só é aceito em `app/layout.tsx`, e é o que garante que `window.Legitimuz`
    existe antes de qualquer efeito de componente cliente rodar. Veja as boas práticas abaixo.
  </Step>

  <Step title="Isole o widget num Client Component">
    ```tsx title="components/VerificationWidget.tsx" theme={null}
    "use client";

    import { useEffect, useRef } from "react";

    export function VerificationWidget({ sdkUrl }: { sdkUrl: string }) {
      const containerRef = useRef<HTMLDivElement | null>(null);

      useEffect(() => {
        if (!containerRef.current) return;
        const handle = window.Legitimuz.mount({ sdkUrl, target: containerRef.current });
        return () => handle.destroy();
      }, [sdkUrl]);

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

    O `"use client"` precisa ser a **primeira linha do arquivo**: um prólogo de diretiva não pode
    vir depois de um comentário. Sem ele, este componente tentaria rodar na renderização do
    servidor, onde `window` não existe.
  </Step>

  <Step title="Mantenha a página no servidor">
    ```tsx title="app/page.tsx" theme={null}
    import { VerificationWidget } from "@/components/VerificationWidget";

    export default function Page() {
      return (
        <main>
          <VerificationWidget sdkUrl={process.env.NEXT_PUBLIC_LEGITIMUZ_SDK_URL!} />
        </main>
      );
    }
    ```

    Sem `"use client"` aqui. A página continua Server Component e passa a `sdkUrl` como prop, como
    faria com qualquer outro filho.
  </Step>

  <Step title="Configure a sdkUrl">
    ```bash title=".env.local" theme={null}
    NEXT_PUBLIC_LEGITIMUZ_SDK_URL=<SUA_SDK_URL>
    ```

    O prefixo `NEXT_PUBLIC_` é obrigatório: o valor precisa chegar ao navegador, e
    `process.env.LEGITIMUZ_SDK_URL` sem prefixo seria `undefined` no componente cliente.

    Numa integração real, a `sdkUrl` não vem de variável de ambiente, ela é emitida por
    verificação. Busque-a num Server Component ou numa Route Handler e passe como prop.
  </Step>
</Steps>

## Confira que funcionou

A primeira tela aparece dentro do container. No console do servidor não deve haver nenhum erro de
`window is not defined`.

## Boas práticas

<Card title="Carregue o SDK com beforeInteractive" icon="checklist" horizontal>
  A estratégia `beforeInteractive` garante que `window.Legitimuz` exista antes de qualquer efeito de
  componente cliente rodar. É a forma recomendada para este script.

  Se a sua arquitetura pede `afterInteractive`, condicione a montagem a um estado que o `onLoad` do
  `<Script>` ativa. Assim o widget só monta quando o SDK estiver disponível.
</Card>

## Próximo passo

<Columns cols={2}>
  <Card title="React" icon="react" href="/guides/web/react">
    O hook completo, com tipos e o cuidado com o StrictMode.
  </Card>

  <Card title="Receber a decisão" icon="webhook" href="/webhooks/introduction">
    Onde o desfecho realmente chega.
  </Card>
</Columns>
