یکپارچه سازی Backend Form Next.js (App Router & Server Actions)
راهنمای کامل پیادهسازی TypeScript و React برای مدیریت فرمهای تماس در Next.js 14/15 با استفاده از نقاط پایانی Lugatu و اقدامات سرور با قرار گرفتن در معرض اعتبار صفر.
1. معماری روتر برنامه Next.js با اقدامات سرور
Next.js Server Actions به طور انحصاری بر روی سرور اجرا میشوند و آنها را برای ارسال درخواستها با کلیدهای خصوصی Lugatu API بدون افشای اسرار در بستههای مشتری ایدهآل میسازد.
'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. مؤلفه فرم سمت مشتری با حالت بارگذاری
Server Action خود را به یک مؤلفه مشتری React 19 / Next.js با نشانگرهای بارگیری در دسترس متصل کنید.
'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>
);
}
امنیت و احراز هویت ثابت
دستورالعمل امنیتی: هرگز LUGATU_API_KEY را با NEXT_PUBLIC_ پیشوند نکنید. فقط متغیرهای سمت سرور خصوصی می توانند کلید API زنده شما را با خیال راحت نگه دارند.
عیب یابی و خطاهای رایج بلع
شما در حال برقراری تماس fetch() از کد مرورگر سمت سرویس گیرنده با یک کلید API هستید. یا به یک Next.js Server Action بروید یا از نقطه پایانی فرم عمومی بدون کلید API استفاده کنید.
سوالات متداول
آیا می توانم این را در صفحات Vercel یا Cloudflare مستقر کنم؟
بله. Server Actions به طور یکپارچه در پلتفرمهای بدون سرور و زمانهای اجرا لبهای که توسط Next.js پشتیبانی میشوند، کار میکنند.
برای ایجاد نقطه پایانی فرم خود آماده هستید؟
در عرض چند ثانیه به صورت رایگان شروع کنید. بدون نیاز به کارت اعتباری