Home / Ghiduri / Integrare formular de contact unghiular (autonom și semnale)
GHID DE INTEGRARE · ANGULAR & SPA

Integrare formular de contact unghiular (autonom și semnale)

Conectați aplicațiile Angular 17/18+ la Lugatu folosind Componente Standalone, Signals reactive și HttpClient pentru livrare fiabilă a formularelor de contact fără a menține un server SMTP.

1. Componentă independentă a formularului de contact cu semnale reactive

Modern Angular favorizează componentele și semnalele independente față de modulele Ng grele. Această implementare oferă un formular de contact accesibil cu încărcare reactivă, erori și stări de succes transmise direct către 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 și Angular Universal Server-to-Server Forwarding

Dacă aplicația dvs. Angular rulează cu Angular SSR (motor Node / Express), puteți trimite interogări printr-un handler de rută pe partea serverului pentru a vă proteja cheia API Lugatu Server-to-Server.

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. Apărare bot și configurație Honeypot

Lugatu inspectează automat câmpul _gotcha. Păstrați-l invizibil pentru vizitatorii umani folosind display:none și tabindex="-1". Spamboții care umple fiecare intrare DOM declanșează suprimarea silențioasă.

tip

Nu utilizați niciodată etichete de formular pentru intrările de honeypot. Lăsați completarea automată dezactivată și excludeți câmpul din numele accesibile cititorului de ecran.

Securitate și autentificare invariantă

Securitate invariabilă: cheile API de la server la server (lug_live_...) nu trebuie să fie niciodată grupate în activele Angular la nivelul clientului sau fișierele environment.ts. Utilizați punctul final public pentru trimiteri directe ale clientului sau redirecționați prin punctele finale ale serverului.

Depanare și erori frecvente de ingestie

HTTP 403 FORBIDDEN_BROWSER_ORIGIN când trimiteți din Angular

Punctele finale de formulare publice permit trimiteri între origini din orice browser. Dacă apelați punctul final de la server la server (POST /api/v1/forms/{id}/submissions) direct din Angular, comutați la punctul final public (POST /api/v1/public/forms/{id}/submissions) sau redirecționați printr-un backend.

Întrebări frecvente

Lugatu suportă Angular SSR cu hidratarea clientului?

Da. Trimiterile de formulare publice Lugatu sunt efectuate prin preluarea de pe partea clientului sau HttpClient după interacțiunea utilizatorului, care este complet compatibil cu Angular SSR și hidratarea clientului.

Sunteți gata să vă creați punctul final al formularului?

Începeți gratuit în câteva secunde. Nu este necesar un card de credit.

Începe gratuit →