통합 가이드 · 프런트엔드 및 NEXT.JS
Next.js 양식 백엔드 통합(앱 라우터 및 서버 작업)
자격 증명 노출이 전혀 없는 Lugatu 엔드포인트 및 서버 작업을 사용하여 Next.js 14/15에서 문의 양식을 처리하기 위한 완전한 TypeScript 및 React 구현 가이드입니다.
1. 서버 작업이 포함된 Next.js 앱 라우터 아키텍처
Next.js 서버 작업은 서버에서만 실행되므로 클라이언트 번들에 비밀을 노출하지 않고 개인 Lugatu API 키를 사용하여 문의를 제출하는 데 이상적입니다.
app/actions/contact.ts
typescript
'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 클라이언트 구성 요소에 연결하세요.
components/ContactForm.tsx
tsx
'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 키를 안전하게 보관할 수 있습니다.
문제 해결 및 일반적인 수집 오류
API 키 요청이 403 FORBIDDEN_BROWSER_ORIGIN을 반환합니다.
API 키를 사용하여 클라이언트 측 브라우저 코드에서 fetch() 호출을 수행하고 있습니다. Next.js 서버 작업으로 전환하거나 API 키 없이 공개 양식 엔드포인트를 사용하세요.
자주 묻는 질문
Vercel 또는 Cloudflare Pages에 배포할 수 있나요?
예. 서버 작업은 Next.js에서 지원하는 서버리스 플랫폼과 에지 런타임 전반에서 원활하게 작동합니다.
양식 끝점을 만들 준비가 되셨나요?
몇 초 안에 무료로 시작해 보세요. 신용 카드가 필요하지 않습니다.