Home / Guider / Integration av vinkelkontaktformulär (fristående och signaler)
INTEGRATIONSGUIDE · ANGULAR & SPA

Integration av vinkelkontaktformulär (fristående och signaler)

Anslut Angular 17/18+-applikationer till Lugatu med hjälp av fristående komponenter, reaktiva signaler och HttpClient för tillförlitlig leverans av kontaktformulär utan att underhålla en SMTP-server.

1. Fristående kontaktformulärkomponent med reaktiva signaler

Modern Angular gynnar fristående komponenter och signaler framför tunga NgModules. Denna implementering ger ett tillgängligt kontaktformulär med reaktiva laddnings-, fel- och framgångsstatusar som skickas direkt till 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 & Angular Universal Server-to-Server Forwarding

Om din Angular-applikation körs med Angular SSR (Node/Express-motor) kan du proxyförfrågningar via en rutthanterare på serversidan för att skydda din Lugatu Server-till-Server API-nyckel.

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. Bot Defense & Honeypot-konfiguration

Lugatu inspekterar _gotcha-fältet automatiskt. Håll det osynligt för mänskliga besökare med display:none och tabindex="-1". Spambots som fyller varje DOM-ingång utlöser tyst undertryckning.

tip

Använd aldrig formuläretiketter för honungskanna. Lämna autoslutförande av och exkludera fältet från skärmläsare tillgängliga namn.

Säkerhet och autentisering Invariant

Säkerhetsinvariant: Server-till-server API-nycklar (lug_live_...) får aldrig paketeras i Angular-tillgångar eller miljö.ts-filer på klientsidan. Använd den offentliga slutpunkten för direkta klientinlämningar eller vidarebefordra via serverslutpunkter.

Felsökning och vanliga förtäringsfel

HTTP 403 FORBIDDEN_BROWSER_ORIGIN när du skickar från Angular

Offentliga slutpunkter tillåter inlämningar från alla webbläsare. Om du anropar server-till-server-slutpunkten (POST /api/v1/forms/{id}/submissions) direkt från Angular, växla till den offentliga slutpunkten (POST /api/v1/public/forms/{id}/submissions) eller vidarebefordra via en backend.

Vanliga frågor

Stöder Lugatu Angular SSR med klienthydrering?

Ja. Inlämning av offentliga formulär från Lugatu utförs via hämtning på klientsidan eller HttpClient efter användarinteraktion, vilket är helt kompatibelt med Angular SSR och klienthydrering.

Är du redo att skapa din formulärslutpunkt?

Kom igång gratis på några sekunder. Inget kreditkort krävs.

Börja gratis →