Home / Panduan / Integrasi Formulir Kontak Astro (Statis & SSR)
PANDUAN INTEGRASI · ASTRO & JAMSTACK

Integrasi Formulir Kontak Astro (Statis & SSR)

Cara menambahkan formulir kontak ke situs statis Astro (SSG) dan rute server hibrid menggunakan titik akhir Lugatu tanpa memelihara server email atau database.

1. Penyerapan Formulir Situs Statis Murni (SSG).

Astro terkenal dengan nol-JavaScript secara default. Dengan Lugatu, Anda dapat menjaga situs Astro Anda 100% statis sambil mengumpulkan pertanyaan dengan formulir HTML standar dan pengambilan sisi klien yang ringan.

src/pages/contact.astro astro
---
// src/pages/contact.astro
---
<form id="astro-contact-form" class="space-y-4 max-w-md">
  <div>
    <label class="block text-sm font-semibold mb-1">Your Name</label>
    <input type="text" name="name" required class="w-full border rounded-xl p-2.5" />
  </div>
  <div>
    <label class="block text-sm font-semibold mb-1">Email Address</label>
    <input type="email" name="email" required class="w-full border rounded-xl p-2.5" />
  </div>
  <div>
    <label class="block text-sm font-semibold mb-1">Message</label>
    <textarea name="message" rows="4" required class="w-full border rounded-xl p-2.5"></textarea>
  </div>

  <input type="text" name="_gotcha" style="display:none !important" tabindex="-1" autocomplete="off" />

  <button type="submit" class="btn-primary-editorial py-2.5 px-6">Send Message</button>
</form>

<script>
  const form = document.getElementById('astro-contact-form') as HTMLFormElement;
  form?.addEventListener('submit', async (e) => {
    e.preventDefault();
    const formData = new FormData(form);

    const payload = {
      fields: {
        name: formData.get('name'),
        email: formData.get('email'),
        message: formData.get('message'),
      },
      honeypot: formData.get('_gotcha') || '',
    };

    const res = await fetch('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
      body: JSON.stringify(payload),
    });

    if (res.ok) {
      alert('Thank you! Message delivered.');
      form.reset();
    }
  });
</script>

2. Rute API Astro Hybrid / SSR dengan Kunci API Server

Jika situs Astro Anda berjalan dalam mode hybrid atau SSR di Cloudflare Pages, Netlify, atau Vercel, teruskan pengiriman dengan aman melalui rute Astro API.

src/pages/api/contact.ts typescript
import type { APIRoute } from 'astro';

export const POST: APIRoute = async ({ request }) => {
  const data = await request.formData();
  const fields = {
    name: data.get('name')?.toString(),
    email: data.get('email')?.toString(),
    message: data.get('message')?.toString(),
  };

  const res = await fetch(`https://www.lugatu.com/api/v1/forms/${import.meta.env.LUGATU_FORM_ID}/submissions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${import.meta.env.LUGATU_API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID(),
    },
    body: JSON.stringify({ fields }),
  });

  return new Response(JSON.stringify({ success: res.ok }), {
    status: res.status,
    headers: { 'Content-Type': 'application/json' },
  });
};

Keamanan & Otentikasi Invarian

Instruksi Keamanan: Jangan pernah mengekspos import.meta.env.LUGATU_API_KEY di tag skrip sisi klien Astro. Skrip klien hanya boleh menggunakan titik akhir publik.

Pemecahan Masalah & Kesalahan Penyerapan Umum

Formulir berfungsi secara lokal tetapi gagal pada produksi Cloudflare/Netlify build

Pastikan variabel lingkungan produksi Anda (LUGATU_FORM_ID dan LUGATU_API_KEY) dikonfigurasi di dasbor hosting Anda.

Pertanyaan yang Sering Diajukan

Bisakah saya menjaga situs Astro saya 100% statis dengan Lugatu?

Ya. Situs statis murni (SSG) dikirimkan langsung ke titik akhir publik Lugatu tanpa memerlukan komputasi server apa pun di penyedia hosting Anda.

Siap membuat titik akhir formulir Anda?

Mulailah secara gratis dalam hitungan detik. Tidak diperlukan kartu kredit.

Mulai Gratis →