Home / מדריכים / Next.js Form Backend שילוב (נתב אפליקציות ופעולות שרת)
מדריך אינטגרציה · FRONTEND & NEXT.JS

Next.js Form Backend שילוב (נתב אפליקציות ופעולות שרת)

מדריך יישום מלא של TypeScript ו-React לטיפול בטפסי יצירת קשר ב-Next.js 14/15 באמצעות נקודות קצה של Lugatu ופעולות שרת עם אפס חשיפת אישורים.

1. ארכיטקטורת נתב האפליקציה של Next.js עם פעולות שרת

Next.js Server Actions מבוצעות באופן בלעדי על השרת, מה שהופך אותן לאידיאליות להגשת פניות עם מפתחות API פרטיים של Lugatu מבלי לחשוף סודות בחבילות לקוח.

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

אתה מבצע קריאה ל-fetch() מקוד דפדפן בצד הלקוח עם מפתח API. עבור לפעולת שרת Next.js או השתמש בנקודת הקצה של הטופס הציבורי ללא מפתח API.

שאלות נפוצות

האם אוכל לפרוס את זה לדפי Vercel או Cloudflare?

כֵּן. פעולות שרת פועלות בצורה חלקה על פני פלטפורמות ללא שרת וזמני ריצה קצה הנתמכים על ידי Next.js.

מוכן ליצור את נקודת הקצה של הטופס שלך?

התחל בחינם תוך שניות. אין צורך בכרטיס אשראי.

התחל בחינם →