lobsite! Masuk Daftar

Dokumentasi /

Formulir

Formulir HTML apa pun di situs Lobsite dapat mengumpulkan pesan: arahkan action-nya ke /_lobsite/forms/<name> dan lakukan deploy. Tidak ada backend untuk ditulis, skrip untuk ditambahkan, atau kunci untuk ditempel. Kiriman masuk ke halaman Kiriman di dasbor dan ke email Anda.

<form action="/_lobsite/forms/contact" method="POST">
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>

Cara kerja formulir

  • Action menamai formulir. /_lobsite/forms/contact adalah formulir contact. Nama berisi huruf kecil, angka, -, dan _. Gunakan satu nama per tujuan (contact, newsletter, quote); beberapa halaman dapat berbagi satu formulir.
  • Formulir ditemukan saat deploy. Deploy membaca file HTML dan mencatat setiap formulir yang mengirim ke /_lobsite/forms/. Formulir harus ada di file HTML dalam folder yang di-deploy: formulir yang hanya ada setelah JavaScript merendernya tidak ditemukan (lihat Framework).
  • Kolom disimpan sesuai nama Anda. Setiap kolom dengan name disimpan, sebagai teks. Kolom bernama email dipakai sebagai Reply-To email notifikasi dan sebagai judul di halaman Kiriman. Unggahan file tidak didukung.
  • Perlindungan spam ditambahkan untuk Anda. Saat halaman disajikan, kolom honeypot tersembunyi dan stempel waktu bertanda tangan ditambahkan ke formulir. Kiriman yang mengisi honeypot atau kembali dalam 2 detik dipisahkan sebagai spam, dan terlalu banyak berturut-turut dari satu pengunjung ditolak.
  • Setelah mengirim, pengunjung melihat halaman terima kasih dengan tautan kembali, atau halaman yang Anda setel dengan redirect.
  • Formulir berfungsi di URL produksi. Deploy pratinjau tidak menerima kiriman, dan situs yang di-deploy tanpa akun menerimanya setelah diklaim.

Tipe formulir

Setiap formulir adalah formulir kontak atau daftar tunggu. Tipe menentukan cara kiriman ditampilkan di halaman Kiriman: baris formulir kontak menampilkan pesan, baris daftar tunggu menampilkan siapa yang bergabung dan dari halaman mana, dan daftar tunggu dihitung di atas tabel. Keduanya mengirim email notifikasi yang sama.

Lobsite memilih tipe saat Anda deploy:

  • Formulir yang pengunjungnya mengisi email dan paling banyak nama adalah daftar tunggu. Kolom tersembunyi, kolom yang diawali _, dan kotak centang (kotak persetujuan) tidak dihitung.
  • Begitu juga formulir bernama waitlist, newsletter, signup, subscribe, early-access, beta, atau notify, apa pun kolomnya.
  • Setiap formulir lainnya adalah formulir kontak.

Untuk memilih sendiri, setel type di lobsite.toml:

[forms.launch]
type = "waitlist"   # or "contact"

Pendaftaran daftar tunggu disimpan selama formulir ada; kiriman lain disimpan selama masa penyimpanan paket (lihat Batas).

Formulir kontak

Halaman lengkap dengan nama, email, dan pesan. Label dan nilai autocomplete membuatnya mudah diisi; atribut required menghentikan kiriman kosong sebelum dikirim.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Contact</title>
</head>
<body>
  <h1>Get in touch</h1>
  <form action="/_lobsite/forms/contact" method="POST">
    <label>Name
      <input name="name" autocomplete="name" required>
    </label>
    <label>Email
      <input name="email" type="email" autocomplete="email" required>
    </label>
    <label>Message
      <textarea name="message" rows="5" required></textarea>
    </label>
    <button type="submit">Send</button>
  </form>
</body>
</html>

Untuk memeriksa kolom yang sama di server dan mengarahkan pengunjung ke halaman terima kasih Anda, tambahkan formulir ke lobsite.toml dan buat thanks.html:

[forms.contact]
required = ["name", "email", "message"]
types    = { email = "email" }
redirect = "/thanks"

Daftar tunggu

Sebelum peluncuran, kolom email saja sudah cukup. Nama formulir menjadikannya daftar tunggu; menyetel type menyatakannya secara eksplisit. Pendaftaran dihitung di halaman Kiriman dan disimpan selama formulir ada.

<form action="/_lobsite/forms/waitlist" method="POST">
  <label for="wl-email">Get early access</label>
  <input id="wl-email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
  <button>Join the waitlist</button>
</form>
[forms.waitlist]
type     = "waitlist"
required = ["email"]
types    = { email = "email" }

Pendaftaran newsletter

Satu kolom sudah cukup. Formulir kedua di situs yang sama mendapat nama sendiri, sehingga pendaftaran dan pesan tetap terpisah di halaman Kiriman dan ekspor. Formulir dengan hanya kolom email (dan paling banyak nama) adalah daftar tunggu: lihat Tipe formulir.

<form action="/_lobsite/forms/newsletter" method="POST">
  <label for="nl-email">Get updates by email</label>
  <input id="nl-email" name="email" type="email" autocomplete="email" required>
  <input type="hidden" name="_redirect" value="/subscribed">
  <button>Subscribe</button>
</form>

_redirect adalah kolom tersembunyi yang memilih halaman setelah mengirim. Harus berupa path atau URL di situs yang sama; redirect di lobsite.toml lebih diutamakan.

Permintaan penawaran

Select, tombol radio, dan kotak centang berfungsi seperti biasa. Kotak centang dengan nama yang sama disimpan sebagai satu nilai yang dipisahkan koma.

<form action="/_lobsite/forms/quote" method="POST">
  <input name="name" autocomplete="name" required>
  <input name="email" type="email" autocomplete="email" required>
  <input name="phone" type="tel" autocomplete="tel">
  <select name="budget">
    <option>Under $1,000</option>
    <option>$1,000 to $5,000</option>
    <option>Over $5,000</option>
  </select>
  <fieldset>
    <legend>Services</legend>
    <label><input type="checkbox" name="services" value="Design"> Design</label>
    <label><input type="checkbox" name="services" value="Development"> Development</label>
    <label><input type="checkbox" name="services" value="Hosting"> Hosting</label>
  </fieldset>
  <textarea name="details" required></textarea>
  <button>Request a quote</button>
</form>

Mengirim tanpa meninggalkan halaman

Untuk menampilkan pesan di tempat alih-alih memuat halaman baru, kirim formulir dengan fetch. Buat isi dengan new FormData(form) agar kolom spam tersembunyi ikut terkirim, dan minta JSON dengan header Accept:

<form id="contact" action="/_lobsite/forms/contact" method="POST">
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <button>Send</button>
  <p id="contact-status" role="status"></p>
</form>
<script>
  const form = document.getElementById("contact");
  const status = document.getElementById("contact-status");
  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    status.textContent = "Sending…";
    const res = await fetch(form.action, {
      method: "POST",
      body: new FormData(form),
      headers: { Accept: "application/json" },
    });
    const answer = await res.json();
    if (answer.ok) {
      form.reset();
      status.textContent = "Thanks! We'll be in touch.";
    } else {
      status.textContent = answer.errors ? Object.entries(answer.errors).map(([field, why]) => `${field}: ${why}`).join(", ") : "Something went wrong. Please try again.";
    }
  });
</script>

Jawabannya {"ok": true}, atau {"ok": false, "errors": {"email": "Required"}} untuk kolom yang tidak lolos, atau {"ok": false, "error": "rate_limited"} (juga too_large, not_found, forms_off). Tanpa skrip, formulir yang sama tetap berfungsi sebagai formulir biasa.

Framework

React, Vue, Svelte, Astro, dan lainnya berfungsi jika formulir ada di HTML hasil build, yang dihasilkan prerendering dan ekspor statis (Astro dan Eleventy secara bawaan, Next.js dengan output: "export", SvelteKit dengan prerender, Nuxt dengan nuxt generate). Pertahankan atribut action dan method di elemen <form> itu sendiri.

Di aplikasi satu halaman, formulir harus ada di HTML hasil build dan tetap seperti yang disajikan: formulir yang hanya ada di JavaScript tidak dicatat dan kirimannya ditolak, dan formulir yang dirender ulang browser kehilangan kolom spam, sehingga pesannya masuk ke Spam.

// React: a plain form element, prerendered into the HTML.
export function Contact() {
  return (
    <form action="/_lobsite/forms/contact" method="POST">
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button>Send</button>
    </form>
  );
}

Pengaturan

Setiap formulir dapat memiliki bagian di lobsite.toml. Semua kunci opsional; pengaturan ikut bersama deploy.

[forms.contact]
type      = "contact"                            # contact or waitlist; inferred when left out
required  = ["email", "message"]                 # fields that can't be empty
types     = { email = "email", phone = "tel" }   # text, email, number, url or tel
redirect  = "/thanks"                            # the page shown after sending
notify    = ["you@example.com"]                  # who gets an email for each message
webhook   = "https://example.com/hooks/contact"  # POSTs each submission as JSON

Kiriman yang gagal required atau types tidak disimpan; pengunjung melihat yang perlu diperbaiki dan tautan kembali. Pada paket gratis, notify hanya dapat berupa email akun Anda dan webhook tidak tersedia.

Membaca kiriman

  • Halaman Kiriman di dasbor menampilkan kiriman setiap formulir dalam satu tabel. Cari, persempit berdasarkan situs dan tipe formulir, dan beralih ke spam untuk melihat yang tertangkap pemeriksaan. Kiriman berstatus Baru sampai Anda membukanya.
  • Setiap pesan dikirim melalui email ke alamat akun Anda, dengan Reply-To disetel ke pengirim.
  • lobsite forms ls mencantumkan formulir Anda; lobsite forms export contact --csv mengunduh kiriman satu formulir. Ekspor CSV di halaman Kiriman mengunduh yang ditampilkan tabel.

Pada paket gratis, formulir berjalan dalam mode terbatas: kuota bulanan per situs, notifikasi hanya ke email akun Anda, dan tanpa webhook. Paket Standard menambahkan webhook, alamat notifikasi terverifikasi apa pun, dan tanpa batas bulanan. Lihat Batas.