Home / Guias / Integração de formulário de contato angular (autônomo e sinais)
GUIA DE INTEGRAÇÃO · ANGULAR & SPA

Integração de formulário de contato angular (autônomo e sinais)

Conecte aplicativos Angular 17/18+ ao Lugatu usando componentes independentes, sinais reativos e HttpClient para entrega confiável de formulários de contato sem manter um servidor SMTP.

1. Componente autônomo de formulário de contato com sinais reativos

O Angular moderno favorece componentes e sinais autônomos em vez de NgModules pesados. Esta implementação fornece um formulário de contato acessível com carregamento reativo, erros e estados de sucesso enviados diretamente ao Lugatu.

contact-form.component.ts typescript
import { Component, signal, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-contact-form',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <form (ngSubmit)="onSubmit()" class="space-y-4 max-w-md">
      <div>
        <label for="name" class="block text-sm font-semibold mb-1">Your Name</label>
        <input id="name" type="text" [(ngModel)]="name" name="name" required class="w-full border rounded-xl p-2.5" />
      </div>
      <div>
        <label for="email" class="block text-sm font-semibold mb-1">Email Address</label>
        <input id="email" type="email" [(ngModel)]="email" name="email" required class="w-full border rounded-xl p-2.5" />
      </div>
      <div>
        <label for="message" class="block text-sm font-semibold mb-1">Message</label>
        <textarea id="message" rows="4" [(ngModel)]="message" name="message" required class="w-full border rounded-xl p-2.5"></textarea>
      </div>

      <!-- Honeypot spam defense -->
      <input type="text" [(ngModel)]="gotcha" name="_gotcha" style="display:none !important" tabindex="-1" autocomplete="off" />

      <button type="submit" [disabled]="isSubmitting()" class="btn-primary-editorial py-2.5 px-6">
        {{ isSubmitting() ? 'Sending...' : 'Send Message' }}
      </button>

      <p *ngIf="isSuccess()" class="text-sm text-green-700 font-medium">Thank you! Your message has been received.</p>
      <p *ngIf="errorMessage()" class="text-sm text-red-600">{{ errorMessage() }}</p>
    </form>
  `,
})
export class ContactFormComponent {
  private http = inject(HttpClient);

  name = signal('');
  email = signal('');
  message = signal('');
  gotcha = signal('');

  isSubmitting = signal(false);
  isSuccess = signal(false);
  errorMessage = signal('');

  onSubmit() {
    if (this.gotcha()) return; // Silent discard for automated bot submissions

    this.isSubmitting.set(true);
    this.errorMessage.set('');

    const payload = {
      fields: {
        name: this.name(),
        email: this.email(),
        message: this.message(),
      },
      honeypot: this.gotcha(),
    };

    this.http.post('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', payload)
      .subscribe({
        next: () => {
          this.isSubmitting.set(false);
          this.isSuccess.set(true);
          this.name.set('');
          this.email.set('');
          this.message.set('');
        },
        error: () => {
          this.isSubmitting.set(false);
          this.errorMessage.set('Submission failed. Please try again.');
        },
      });
  }
}

2. SSR e encaminhamento universal angular de servidor para servidor

Se o seu aplicativo Angular for executado com Angular SSR (mecanismo Node/Express), você poderá fazer proxy de consultas por meio de um manipulador de rota do lado do servidor para proteger sua chave de API Lugatu servidor a servidor.

server.ts typescript
// Express / Node backend endpoint in Angular SSR
server.post('/api/contact', async (req, res) => {
  const { name, email, message, _gotcha } = req.body;
  if (_gotcha) return res.status(200).json({ ok: true });

  try {
    const response = await fetch(`https://www.lugatu.com/api/v1/forms/${process.env.LUGATU_FORM_ID}/submissions`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.LUGATU_API_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': crypto.randomUUID(),
      },
      body: JSON.stringify({ fields: { name, email, message } }),
    });

    res.status(response.status).json({ ok: response.ok });
  } catch (error) {
    res.status(500).json({ error: 'Failed to deliver message' });
  }
});

3. Defesa de bot e configuração de honeypot

Lugatu inspeciona o campo _gotcha automaticamente. Mantenha-o invisível para visitantes humanos usando display:none e tabindex="-1". Spambots que preenchem cada entrada do DOM acionam a supressão silenciosa.

tip

Nunca use rótulos de formulário para entradas de honeypot. Deixe o preenchimento automático desativado e exclua o campo dos nomes acessíveis pelo leitor de tela.

Invariante de segurança e autenticação

Invariante de segurança: as chaves de API de servidor para servidor (lug_live_...) nunca devem ser agrupadas em ativos Angular do lado do cliente ou em arquivos Environment.ts. Use o endpoint público para envios diretos do cliente ou encaminhamento por meio de endpoints do servidor.

Solução de problemas e erros comuns de ingestão

HTTP 403 FORBIDDEN_BROWSER_ORIGIN ao enviar do Angular

Os endpoints de formulário público permitem envios de origem cruzada de qualquer navegador. Se você estiver chamando o endpoint de servidor para servidor (POST /api/v1/forms/{id}/submissions) diretamente do Angular, mude para o endpoint público (POST /api/v1/public/forms/{id}/submissions) ou encaminhe por meio de um back-end.

Perguntas frequentes

Lugatu suporta SSR Angular com hidratação do cliente?

Sim. Os envios de formulários públicos do Lugatu são realizados por meio de busca do lado do cliente ou HttpClient após a interação do usuário, o que é totalmente compatível com Angular SSR e hidratação do cliente.

Pronto para criar o endpoint do seu formulário?

Comece gratuitamente em segundos. Não é necessário cartão de crédito.

Comece grátis →