Angular Contact Form 통합(독립형 및 신호)
SMTP 서버를 유지 관리하지 않고도 안정적인 문의 양식 전달을 위해 독립 실행형 구성 요소, 반응형 신호 및 HttpClient를 사용하여 Angular 17/18+ 애플리케이션을 Lugatu에 연결하세요.
1. 반응 신호가 포함된 독립형 문의 양식 구성 요소
Modern Angular는 무거운 NgModule보다 독립형 구성 요소 및 신호를 선호합니다. 이 구현은 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 및 Angular Universal 서버 간 전달
Angular 애플리케이션이 Angular SSR(노드/익스프레스 엔진)과 함께 실행되는 경우 서버 측 경로 핸들러를 통해 쿼리를 프록시하여 Lugatu 서버 간 API 키를 보호할 수 있습니다.
// 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. 봇 방어 및 허니팟 구성
Lugatu는 _gotcha 필드를 자동으로 검사합니다. display:none 및 tabindex="-1"을 사용하여 방문자에게 보이지 않게 유지하세요. 모든 DOM 입력을 채우는 스팸봇은 자동 억제를 트리거합니다.
허니팟 입력에는 양식 레이블을 사용하지 마십시오. 자동 완성을 꺼진 상태로 두고 화면 판독기에서 액세스할 수 있는 이름에서 해당 필드를 제외합니다.
보안 및 인증 불변
보안 불변성: 서버 간 API 키(lug_live_...)는 클라이언트 측 Angular 자산 또는 Environment.ts 파일에 번들로 포함되어서는 안 됩니다. 직접 클라이언트 제출을 위해 공개 엔드포인트를 사용하거나 서버 엔드포인트를 통해 전달하세요.
문제 해결 및 일반적인 수집 오류
공개 양식 끝점은 모든 브라우저에서 원본 간 제출을 허용합니다. Angular에서 직접 서버 간 엔드포인트(POST /api/v1/forms/{id}/submissions)를 호출하는 경우 퍼블릭 엔드포인트(POST /api/v1/public/forms/{id}/submissions)로 전환하거나 백엔드를 통해 전달하세요.
자주 묻는 질문
Lugatu는 클라이언트 수화 기능을 갖춘 Angular SSR을 지원합니까?
예. Lugatu 공개 양식 제출은 사용자 상호 작용 후 클라이언트 측 가져오기 또는 HttpClient를 통해 수행되며, 이는 Angular SSR 및 클라이언트 하이드레이션과 완벽하게 호환됩니다.
양식 끝점을 만들 준비가 되셨나요?
몇 초 안에 무료로 시작해 보세요. 신용 카드가 필요하지 않습니다.