Ana Sayfa / Rehberler / Next.js Form Altyapısı Entegrasyonu (App Router & Server Actions)
ENTEGRASYON REHBERİ · FRONTEND VE NEXT.JS

Next.js Form Altyapısı Entegrasyonu (App Router & Server Actions)

Next.js 14/15 App Router ve Server Actions kullanarak form gönderimlerini Lugatu ile yönetme üzerine gizli anahtarları açıkta bırakmayan eksiksiz TypeScript rehberi.

1. Next.js App Router ve Server Actions Mimarisi

Server Actions yalnızca sunucuda çalışır. Böylece gizli Lugatu API anahtarınızı istemci paketine sızdırmadan güvenle kullanabilirsiniz.

app/actions/contact.ts typescript
'use server';

export async function submitContact(prevState: any, formData: FormData) {
  // Bal küpü (honeypot) spam botu kontrolü
  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: 'Tüm alanlar zorunludur.' };
  }

  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: 'Form gönderilemedi.' };
    }

    return { success: true, error: null };
  } catch (err) {
    return { success: false, error: 'Ağ hatası oluştu.' };
  }
}

2. Yüklenme Durumu Yönetimli İstemci Bileşeni

Server Action fonksiyonunuzu React 19 / Next.js istemci bileşeniyle bağlayarak anında geri bildirim sunun.

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">Ad Soyad</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">E-posta</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">Mesajınız</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 ? 'Gönderiliyor...' : 'Mesajı Gönder'}
      </button>

      {state.success && <p className="text-emerald-700 text-sm">Teşekkürler! Mesajınız alındı.</p>}
      {state.error && <p className="text-red-700 text-sm">{state.error}</p>}
    </form>
  );
}

Güvenlik ve Kimlik Doğrulama Standardı

Güvenlik Talimatı: LUGATU_API_KEY değişkenini asla NEXT_PUBLIC_ önekiyle tanımlamayın. Yalnızca sunucu ortam değişkenleri gizli anahtar barındırabilir.

Sorun Giderme ve Yaygın Hatalar

FORBIDDEN_BROWSER_ORIGIN hatası (403)

API anahtarını tarayıcı tarafındaki bir fetch çağrısında kullanıyorsunuz. Çağrıyı Next.js Server Action içine taşıyın veya genel endpoint’i kullanın.

Sıkça Sorulan Sorular

Vercel üzerinde ekstra bir sunucu kurmam gerekir mi?

Hayır. Next.js Server Actions sunucusuz fonksiyon olarak otomatik çalışır ve Lugatu ile entegre olur.

Kendi formunuzu oluşturmaya hazır mısınız?

Saniyeler içinde ücretsiz başlayın. Kredi kartı gerektirmez.

Ücretsiz Başlayın →