Integrace backendu formuláře Next.js (aplikační směrovač a akce serveru)
Kompletní průvodce implementací TypeScript a React pro zpracování kontaktních formulářů v Next.js 14/15 pomocí koncových bodů Lugatu a akcí serveru s nulovým vystavením pověření.
1. Architektura routeru Next.js s akcemi serveru
Next.js Server Actions se spouští výhradně na serveru, takže jsou ideální pro odesílání dotazů pomocí soukromých klíčů Lugatu API bez odhalení tajemství v klientských balíčcí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. Komponenta formuláře na straně klienta se stavem načítání
Připojte svou akci serveru ke klientské komponentě React 19 / Next.js s dostupnými indikátory načítání.
'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>
);
}
Neměnné zabezpečení a ověřování
Bezpečnostní instrukce: Nikdy před LUGATU_API_KEY předponu NEXT_PUBLIC_. Pouze soukromé proměnné na straně serveru mohou bezpečně uchovávat váš živý klíč API.
Odstraňování problémů a běžné chyby při příjmu
Provádíte volání fetch() z kódu prohlížeče na straně klienta pomocí klíče API. Přepněte na akci serveru Next.js nebo použijte veřejný koncový bod formuláře bez klíče API.
Často kladené otázky
Mohu to nasadit na Vercel nebo Cloudflare Pages?
Ano. Server Actions bezproblémově fungují napříč platformami bez serveru a okrajovými běhovými prostředími podporovanými Next.js.
Jste připraveni vytvořit koncový bod formuláře?
Začněte zdarma během několika sekund. Není vyžadována žádná kreditní karta.