Angular Contact Form Integration (Standalone at Signals)
Ikonekta ang Angular 17/18+ na application sa Lugatu gamit ang Standalone Components, reactive Signals, at HttpClient para sa maaasahang paghahatid ng contact form nang hindi pinapanatili ang isang SMTP server.
1. Standalone Contact Form Component na may Reactive Signals
Pinapaboran ng Modern Angular ang mga Standalone na Bahagi at Signal kaysa sa mabibigat na NgModule. Ang pagpapatupad na ito ay nagbibigay ng naa-access na form sa pakikipag-ugnayan na may reaktibong pag-load, error, at mga katayuan ng tagumpay na direktang nagsusumite sa 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. SSR at Angular Universal Server-to-Server Forwarding
Kung tumatakbo ang iyong Angular na application gamit ang Angular SSR (Node / Express engine), maaari kang mag-proxy ng mga katanungan sa pamamagitan ng tagapangasiwa ng ruta sa gilid ng server upang protektahan ang iyong Lugatu Server-to-Server API key.
// 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 at Honeypot Configuration
Awtomatikong sinusuri ni Lugatu ang field na _gotcha. Panatilihing hindi nakikita ng mga bisitang tao gamit ang display:none at tabindex="-1". Ang mga spambot na pumupuno sa bawat input ng DOM ay nagti-trigger ng tahimik na pagsugpo.
Huwag gumamit ng mga label ng form para sa mga input ng honeypot. Iwanang naka-off ang autocomplete at ibukod ang field mula sa mga naa-access na pangalan ng screen-reader.
Invariant ng Seguridad at Pagpapatotoo
Security Invariant: Ang mga server-to-server na API key (lug_live_...) ay hindi dapat isama sa client-side Angular asset o environment.ts file. Gamitin ang pampublikong endpoint para sa direktang pagsusumite ng kliyente o ipasa sa pamamagitan ng mga endpoint ng server.
Pag-troubleshoot at Mga Karaniwang Error sa Pag-ingest
Pinapahintulutan ng mga endpoint ng pampublikong anyo ang mga cross-origin na pagsusumite mula sa anumang browser. Kung direktang tinatawagan mo ang server-to-server endpoint (POST /api/v1/forms/{id}/submissions) mula sa Angular, lumipat sa pampublikong endpoint (POST /api/v1/public/forms/{id}/submissions) o ipasa sa pamamagitan ng backend.
Mga Madalas Itanong
Sinusuportahan ba ng Lugatu ang Angular SSR na may hydration ng kliyente?
Oo. Ang mga pagsusumite ng pampublikong form sa Lugatu ay isinasagawa sa pamamagitan ng client-side fetch o HttpClient pagkatapos ng pakikipag-ugnayan ng user, na ganap na tugma sa Angular SSR at client hydration.
Handa nang gawin ang endpoint ng iyong form?
Magsimula nang libre sa ilang segundo. Walang kinakailangang credit card.