> ## Documentation Index
> Fetch the complete documentation index at: https://legitimuz.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Angular

> Monte o widget num app Angular standalone, com ngAfterViewInit e os callbacks expostos como Output.

Ao final deste guia o fluxo de verificação abre num app Angular, encapsulado num componente que
expõe os callbacks do SDK como `@Output`.

## Pré-requisitos

* Node.js 20 ou superior e o Angular CLI (`npm install -g @angular/cli`).
* Uma `sdkUrl` emitida pelo seu backend, como no [passo 6](/setup/integrate).

## Monte o fluxo

<Steps>
  <Step title="Carregue o SDK">
    ```html title="src/index.html" theme={null}
    <script src="https://sdk.legitimuz.com/v1/websdk.js"></script>
    ```

    O script registra `window.Legitimuz`.
  </Step>

  <Step title="Declare o global">
    O build de CDN não traz tipos. Reaproveite a declaração do
    [guia de React](/frameworks/react) — ela espelha `packages/websdk/src/types.ts` e serve a
    qualquer framework.
  </Step>

  <Step title="Escreva o componente">
    ```ts title="src/app/verification-widget.component.ts" theme={null}
    import {
      AfterViewInit,
      Component,
      ElementRef,
      EventEmitter,
      Input,
      OnDestroy,
      Output,
      ViewChild,
    } from "@angular/core";
    import type {
      LegitimuzWidgetHandle,
      WebSdkCancelResult,
      WebSdkCompleteResult,
      WebSdkError,
      WebSdkEvent,
    } from "./legitimuz";

    /** O único componente do app que toca em window.Legitimuz. */
    @Component({
      selector: "app-verification-widget",
      standalone: true,
      template: `<div #container style="height: 640px"></div>`,
    })
    export class VerificationWidgetComponent implements AfterViewInit, OnDestroy {
      @Input({ required: true }) sdkUrl!: string;

      @Output() ready = new EventEmitter<void>();
      @Output() event = new EventEmitter<WebSdkEvent>();
      @Output() complete = new EventEmitter<WebSdkCompleteResult>();
      @Output() cancel = new EventEmitter<WebSdkCancelResult>();
      @Output() error = new EventEmitter<WebSdkError>();

      @ViewChild("container") private container!: ElementRef<HTMLDivElement>;
      private handle?: LegitimuzWidgetHandle;

      ngAfterViewInit() {
        this.handle = window.Legitimuz.mount({
          sdkUrl: this.sdkUrl,
          target: this.container.nativeElement,
          onReady: () => this.ready.emit(),
          onEvent: (e) => this.event.emit(e),
          onComplete: (r) => this.complete.emit(r),
          onCancel: (r) => this.cancel.emit(r),
          onError: (e) => this.error.emit(e),
        });
      }

      ngOnDestroy() {
        this.handle?.destroy();
      }
    }
    ```

    `ngAfterViewInit` é o primeiro momento em que o `@ViewChild` existe. Montar em `ngOnInit`
    falharia, porque o `<div>` ainda não foi criado.
  </Step>

  <Step title="Use no componente raiz">
    ```ts title="src/app/app.component.ts" theme={null}
    import { Component } from "@angular/core";
    import { VerificationWidgetComponent } from "./verification-widget.component";
    import { environment } from "../environments/environment";
    import type { WebSdkCompleteResult, WebSdkError, WebSdkEvent } from "./legitimuz";

    @Component({
      selector: "app-root",
      standalone: true,
      imports: [VerificationWidgetComponent],
      template: `
        <app-verification-widget
          [sdkUrl]="sdkUrl"
          (ready)="status = 'pronto'"
          (event)="onEvent($event)"
          (complete)="onComplete($event)"
          (cancel)="status = 'cancelado'"
          (error)="onError($event)"
        ></app-verification-widget>

        <p>{{ status }}</p>
        <ul>
          @for (entry of log; track $index) {
            <li>{{ entry }}</li>
          }
        </ul>
      `,
    })
    export class AppComponent {
      sdkUrl = environment.sdkUrl;
      status = "montando";
      log: string[] = [];

      onEvent(e: WebSdkEvent) {
        this.log.push(e.type);
      }

      // "o fluxo terminou", não "deu certo": status é "submitted" ou "abandoned"
      onComplete(r: WebSdkCompleteResult) {
        this.status = `fim: ${r.status}`;
      }

      onError(e: WebSdkError) {
        this.status = `erro ${e.code}`;
        this.log.push(e.user_message);
      }
    }
    ```
  </Step>

  <Step title="Configure a sdkUrl">
    Angular não lê `.env`. O caminho da própria ferramenta é o arquivo de environment, trocado no
    build por `fileReplacements`:

    ```ts title="src/environments/environment.ts" theme={null}
    export const environment = {
      production: false,
      sdkUrl: "<SUA_SDK_URL>",
    };
    ```

    Numa integração real a `sdkUrl` é emitida por verificação e vem do seu backend em tempo de
    execução — o environment serve para apontar o endereço desse backend, não para guardar uma
    `sdkUrl`.
  </Step>
</Steps>

## Confira que funcionou

A primeira tela aparece dentro do container e o `status` vira `pronto`. O console não deve trazer
aviso de elemento desconhecido.

## Se você renderizar o custom element

O componente acima monta num `<div>` comum via `mount()`, e por isso não precisa de schema nenhum.
O SDK também expõe o custom element `<legitimuz-websdk>`. **Só nesse caso** o componente precisa
declarar:

```ts theme={null}
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";

@Component({
  // ...
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
```

Declare no componente que usa a tag, não no app inteiro: o resto do app mantém a checagem normal de
elemento desconhecido do Angular.

## Próximo passo

<Columns cols={2}>
  <Card title="Opções do mount()" icon="settings-2" href="/web-sdk/options">
    Aparência, idioma, timeout e todos os callbacks.
  </Card>

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