Integracja z formularzem kontaktowym Angular (samodzielny i sygnały)
Połącz aplikacje Angular 17/18+ z Lugatu, korzystając z samodzielnych komponentów, sygnałów reaktywnych i HttpClient, aby zapewnić niezawodne dostarczanie formularzy kontaktowych bez konieczności utrzymywania serwera SMTP.
1. Samodzielny komponent formularza kontaktowego z sygnałami reaktywnymi
Modern Angular faworyzuje samodzielne komponenty i sygnały zamiast ciężkich modułów Ng. Ta implementacja zapewnia dostępny formularz kontaktowy z reaktywnym ładowaniem, błędami i stanami powodzenia przesyłanymi bezpośrednio do Lugatu.
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. Przekazywanie SSR i Angular Universal Server-to-Server
Jeśli Twoja aplikacja Angular działa z Angular SSR (silnik Node/Express), możesz przesyłać zapytania proxy przez procedurę obsługi tras po stronie serwera, aby chronić swój klucz API Lugatu Server-to-Server.
// 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. Konfiguracja obrony przed botami i Honeypota
Lugatu automatycznie sprawdza pole _gotcha. Trzymaj go niewidocznym dla odwiedzających, używając display:none i tabindex="-1". Roboty spamujące wypełniające każde wejście DOM powodują ciche tłumienie.
Nigdy nie używaj etykiet formularzy do wprowadzania danych w Honeypot. Pozostaw autouzupełnianie wyłączone i wyklucz pole z nazw dostępnych dla czytnika ekranu.
Niezmiennik bezpieczeństwa i uwierzytelniania
Niezmiennik bezpieczeństwa: Klucze API między serwerami (lug_live_...) nigdy nie mogą być pakowane w zasoby Angular po stronie klienta lub pliki Environment.ts. Użyj publicznego punktu końcowego do bezpośredniego przesyłania danych przez klientów lub przesyłania dalej za pośrednictwem punktów końcowych serwera.
Rozwiązywanie problemów i typowe błędy przetwarzania
Publiczne punkty końcowe formularzy umożliwiają przesyłanie danych z różnych źródeł z dowolnej przeglądarki. Jeśli wywołujesz punkt końcowy serwer-serwer (POST /api/v1/forms/{id}/submissions) bezpośrednio z Angular, przełącz się na publiczny punkt końcowy (POST /api/v1/public/forms/{id}/submissions) lub przekaż dalej przez backend.
Często zadawane pytania
Czy Lugatu obsługuje Angular SSR przy nawodnieniu klienta?
Tak. Przesyłanie formularzy publicznych Lugatu odbywa się za pośrednictwem pobierania po stronie klienta lub HttpClient po interakcji użytkownika, co jest w pełni kompatybilne z Angular SSR i nawodnieniem klienta.
Gotowy do utworzenia punktu końcowego formularza?
Rozpocznij bezpłatnie w ciągu kilku sekund. Nie jest wymagana karta kredytowa.