> ## 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 no [passo 6](/setup/integrate).
* O [guia de React](/frameworks/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 a armadilha 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`.

## A armadilha deste framework

<Warning>
  Não use `strategy="afterInteractive"` para este script. `afterInteractive` carrega **depois** da
  hidratação, e o `useEffect` do componente cliente pode rodar antes disso — aí
  `window.Legitimuz` é `undefined` e a montagem estoura. A falha é intermitente: aparece em rede
  lenta e some no seu ambiente local, que é o pior tipo de bug para achar depois.

  Se você precisa de `afterInteractive` por outro motivo, então guarde o efeito com um estado que o
  `onLoad` do `<Script>` liga, e só monte quando ele virar verdadeiro.
</Warning>

## Próximo passo

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

  <Card title="7. Testar" icon="play" href="/setup/test">
    Rode a jornada ponta a ponta e veja a decisão chegar.
  </Card>
</Columns>
