Tích hợp phụ trợ biểu mẫu Next.js (Hành động của bộ định tuyến ứng dụng và máy chủ)
Hướng dẫn triển khai TypeScript và React hoàn chỉnh để xử lý các biểu mẫu liên hệ trong Next.js 14/15 bằng cách sử dụng điểm cuối Lugatu và Hành động máy chủ mà không cần hiển thị thông tin xác thực.
1. Kiến trúc bộ định tuyến ứng dụng Next.js với các hành động của máy chủ
Hành động máy chủ Next.js thực thi độc quyền trên máy chủ, khiến chúng trở nên lý tưởng để gửi yêu cầu bằng khóa API Lugatu riêng tư mà không làm lộ bí mật trong gói ứng dụng khách.
'use server';
export async function submitContact(prevState: any, formData: FormData) {
// Silent rejection of automated bot submissions via honeypot trap
const honeypot = (formData.get('_gotcha') as string) || '';
if (honeypot) {
return { success: true, error: null };
}
const name = formData.get('name') as string;
const email = formData.get('email') as string;
const message = formData.get('message') as string;
if (!name || !email || !message) {
return { success: false, error: 'All fields are required.' };
}
const payload = {
fields: { name, email, message },
};
try {
const res = 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(payload),
});
if (!res.ok) {
return { success: false, error: 'Failed to submit form.' };
}
return { success: true, error: null };
} catch (err) {
return { success: false, error: 'Network error occurred.' };
}
}
2. Thành phần biểu mẫu phía máy khách với trạng thái tải
Kết nối Hành động máy chủ của bạn với thành phần máy khách React 19 / Next.js với các chỉ báo tải có thể truy cập được.
'use client';
import { useActionState } from 'react';
import { submitContact } from '@/app/actions/contact';
export function ContactForm() {
const [state, formAction, isPending] = useActionState(submitContact, { success: false, error: null });
return (
<form action={formAction} className="space-y-4 max-w-md">
<div>
<label className="block text-sm font-semibold mb-1">Name</label>
<input name="name" required className="w-full border rounded-xl p-2.5" />
</div>
<div>
<label className="block text-sm font-semibold mb-1">Email</label>
<input type="email" name="email" required className="w-full border rounded-xl p-2.5" />
</div>
<div>
<label className="block text-sm font-semibold mb-1">Message</label>
<textarea name="message" rows={4} required className="w-full border rounded-xl p-2.5" />
</div>
<input type="text" name="_gotcha" style={{ display: 'none' }} tabIndex={-1} autoComplete="off" />
<button type="submit" disabled={isPending} className="btn-primary-editorial w-full py-2.5">
{isPending ? 'Sending...' : 'Send Message'}
</button>
{state.success && <p className="text-emerald-700 text-sm">Thank you! Your message was received.</p>}
{state.error && <p className="text-red-700 text-sm">{state.error}</p>}
</form>
);
}
Bảo mật & xác thực bất biến
Hướng dẫn bảo mật: Không bao giờ thêm tiền tố LUGATU_API_KEY vào NEXT_PUBLIC_. Chỉ các biến phía máy chủ riêng tư mới có thể giữ khóa API trực tiếp của bạn một cách an toàn.
Khắc phục sự cố và các lỗi nhập thường gặp
Bạn đang thực hiện lệnh gọi tìm nạp() từ mã trình duyệt phía máy khách bằng khóa API. Chuyển sang Hành động máy chủ Next.js hoặc sử dụng điểm cuối biểu mẫu công khai mà không cần khóa API.
Câu hỏi thường gặp
Tôi có thể triển khai tính năng này lên Trang Vercel hoặc Cloudflare không?
Đúng. Tác vụ máy chủ hoạt động liền mạch trên các nền tảng không có máy chủ và thời gian chạy biên được Next.js hỗ trợ.
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.