Интеграция на бекенда на формите на Next.js (действия на рутера на приложението и сървъра)
Пълно ръководство за внедряване на TypeScript и React за работа с формуляри за контакт в Next.js 14/15 с помощта на крайни точки на Lugatu и действия на сървъра с нулево излагане на идентификационни данни.
1. Архитектура на рутер за приложение Next.js със сървърни действия
Сървърните действия на Next.js се изпълняват изключително на сървъра, което ги прави идеални за изпращане на запитвания с частни 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. Компонент на формуляр от страна на клиента със състояние на зареждане
Свържете вашето сървърно действие към клиентски компонент на 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, или използвайте крайната точка на публичната форма без API ключ.
Често задавани въпроси
Мога ли да внедря това във Vercel или Cloudflare Pages?
да Сървърните действия работят безпроблемно в безсървърни платформи и периферни среди, поддържани от Next.js.
Готови ли сте да създадете вашата крайна точка на формуляр?
Започнете безплатно за секунди. Не се изисква кредитна карта.