Tích hợp biểu mẫu liên hệ React (Ứng dụng Vite & một trang)
Cách thêm biểu mẫu liên hệ và phản hồi vào Ứng dụng một trang React (SPA) được xây dựng bằng Vite hoặc Tạo ứng dụng React, có tính năng chống spam honeypot và thông báo hộp thư đến tức thì.
1. Thành phần biểu mẫu liên hệ React tiêu chuẩn với Vite
Thành phần React nhẹ này sử dụng móc React tiêu chuẩn (useState) và API tìm nạp của trình duyệt để gửi trực tiếp đến điểm cuối công khai Lugatu của bạn. Không cần thư viện biểu mẫu bên ngoài hoặc máy chủ phụ trợ.
import React, { useState } from 'react';
export function ContactForm() {
const [formData, setFormData] = useState({ name: '', email: '', message: '', _gotcha: '' });
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
const [errorMessage, setErrorMessage] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (formData._gotcha) return; // Silent discard for automated bot traps
setStatus('submitting');
setErrorMessage('');
try {
const response = await fetch('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
fields: {
name: formData.name,
email: formData.email,
message: formData.message,
},
honeypot: formData._gotcha,
}),
});
if (!response.ok) {
throw new Error('Failed to deliver message');
}
setStatus('success');
setFormData({ name: '', email: '', message: '', _gotcha: '' });
} catch (err: any) {
setStatus('error');
setErrorMessage(err.message || 'Submission error. Please try again.');
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4 max-w-md">
<div>
<label htmlFor="react-name" className="block text-sm font-semibold mb-1">Your Name</label>
<input
id="react-name"
type="text"
required
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<div>
<label htmlFor="react-email" className="block text-sm font-semibold mb-1">Email Address</label>
<input
id="react-email"
type="email"
required
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<div>
<label htmlFor="react-message" className="block text-sm font-semibold mb-1">Message</label>
<textarea
id="react-message"
rows={4}
required
value={formData.message}
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
className="w-full border rounded-xl p-2.5"
/>
</div>
<!-- Honeypot spam defense -->
<input
type="text"
name="_gotcha"
value={formData._gotcha}
onChange={(e) => setFormData({ ...formData, _gotcha: e.target.value })}
style={{ display: 'none' }}
tabIndex={-1}
autoComplete="off"
/>
<button
type="submit"
disabled={status === 'submitting'}
className="btn-primary-editorial py-2.5 px-6"
>
{status === 'submitting' ? 'Sending...' : 'Send Message'}
</button>
{status === 'success' && (
<p className="text-sm text-green-700 font-medium">Thank you! Your message was delivered.</p>
)}
{status === 'error' && (
<p className="text-sm text-red-600">{errorMessage}</p>
)}
</form>
);
}
2. Tích hợp với React Hook Form và Formik
Mô hình gửi JSON tiêu chuẩn Lugatu tích hợp dễ dàng với các thư viện xác thực biểu mẫu như React Hook Form, Formik hoặc Zod. Truyền trực tiếp các giá trị được tuần tự hóa vào đối tượng tải trọng của trường.
// React Hook Form submission handler
const onSubmit = async (data: FormValues) => {
const res = await fetch(`https://www.lugatu.com/api/v1/public/forms/${import.meta.env.VITE_LUGATU_FORM_ID}/submissions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fields: data }),
});
return res.ok;
};
3. Biến môi trường & Phân tách bí mật trong React
Trong Vite, các biến công khai có tiền tố là VITE_. Sử dụng VITE_LUGATU_FORM_ID cho ID biểu mẫu công khai. Không bao giờ để lộ khóa API từ máy chủ đến máy chủ (lug_live_...) bên trong mã nguồn hoặc kho lưu trữ phía máy khách.
Khóa API trực tiếp bắt đầu bằng lug_live_ được dành riêng để thực thi từ máy chủ đến máy chủ. Mọi yêu cầu trình duyệt được gửi bằng khóa API trực tiếp đều bị từ chối bằng HTTP 403.
Bảo mật & xác thực bất biến
Bất biến bảo mật: Không bao giờ thêm tiền tố các khóa API trực tiếp bằng VITE_ hoặc REACT_APP_. Máy khách trình duyệt phải gửi độc quyền tới các điểm cuối công khai mà không cần khóa API.
Khắc phục sự cố và các lỗi nhập thường gặp
Đảm bảo bạn đang gửi tới điểm cuối công khai (https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions). Điểm cuối từ máy chủ đến máy chủ (POST /api/v1/forms/{id}/submissions) chặn rõ ràng nguồn gốc của trình duyệt.
Câu hỏi thường gặp
Tôi có thể sử dụng React Hook Form hoặc Formik với Lugatu không?
Đúng. Lugatu chấp nhận JSON tiêu chuẩn với đối tượng trường. Bất kỳ thư viện biểu mẫu React nào cũng có thể tuần tự hóa các giá trị của nó và gửi đến điểm cuối công khai.
Bạn đã sẵn sàng tạo điểm cuối biểu mẫu chưa?
Bắt đầu miễn phí trong vài giây. Không cần thẻ tín dụng.