Formulir kontak di situs statis5 menit baca
Menambahkan formulir kontak di Netlify tanpa Netlify Forms
Jalankan formulir kontak di situs Netlify tanpa Netlify Forms: tanpa deteksi saat build, kiriman JSON dari React, dan formulir terpisah untuk deploy preview.
Jangan pasang data-netlify di formulir dan arahkan action-nya ke endpoint Ikiform Anda; Netlify lalu menyajikan halaman tanpa menyentuh kirimannya. Formulir React dan Vue tidak butuh salinan HTML tersembunyi, dan bisa mengirim JSON. Atur ID formulir berbeda untuk deploy preview di netlify.toml, karena host preview tidak cocok dengan situs Anda di Allowed domains.
Apa yang berbeda di Netlify
Netlify adalah satu-satunya host statis besar yang punya fitur formulir bawaan. Netlify Forms membaca HTML yang di-deploy setelah setiap build, mencari formulir bertanda data-netlify atau netlify, dan menerima kiriman ke situs Anda sendiri untuk formulir tersebut. Setiap kiriman lain ke halaman statis gagal, dan di Netlify gagalnya dengan 404, bukan 405:
curl -i -X POST -d "message=hello" https://your-site.netlify.app/contact/HTTP/2 404
server: Netlify
cache-status: "Netlify Edge"; fwd=method; fwd-status=404
content-length: 0404 itu membuat orang mencari halaman yang hilang padahal tidak hilang. Artinya tidak ada formulir terdeteksi yang cocok dengan kiriman. Perlu tidaknya memakai Netlify Forms adalah pertanyaan terpisah, dan perbandingan Ikiform vs Netlify Forms menjawabnya apa adanya: jika situs Anda akan selalu di Netlify dan formulirnya HTML biasa, Netlify Forms lebih sedikit kerjanya. Halaman ini untuk kasus lainnya.
| Situasi Anda | Mengapa Netlify Forms jadi penghalang |
|---|---|
| Formulir dirender oleh React, Vue, atau Svelte | Build mem-parsing HTML statis, jadi formulir yang dirender di klien butuh duplikat tersembunyi agar ditemukan Netlify |
Anda ingin mengirim JSON dari fetch | Netlify Forms hanya menerima body urlencoded dan multipart |
| Situs mungkin pindah ke host lain | Formulir mengirim ke domain Anda sendiri, jadi hanya berfungsi selama Netlify yang menyajikan domain itu |
| Pesan harus sampai ke webhook yang Anda verifikasi | Ikiform menandatangani setiap pengiriman dengan header Standard Webhooks dan mencobanya ulang |
- Dengan Netlify Forms, Netlify memindai HTML setiap deploy untuk mencari formulir bertanda data-netlify.
- Formulir yang ditemukannya menerima kiriman ke situs Anda sendiri, dan Netlify menyimpannya.
- Formulir yang tidak ditemukan, seperti yang dirender JavaScript tanpa salinan tersembunyi, mendapat 404 di setiap kiriman.
- Dengan Ikiform, tidak ada yang perlu ditemukan saat build.
- Formulir mengirim langsung ke ikiform.com, sebagai HTML atau JSON, lalu Ikiform menyimpannya dan mengirimi Anda email.
Memindahkan formulir dari Netlify Forms
- Hapus
data-netlifyataunetlify,netlify-honeypot, dandata-netlify-recaptchadari formulir, serta input tersembunyiform-name. Jika dibiarkan,form-namedisimpan sebagai field biasa. - Hapus salinan statis tersembunyi dari formulir JavaScript, seperti di bawah. Netlify hanya membutuhkannya untuk mendeteksi formulir.
- Atur
action, atau URLfetch, ke endpoint Ikiform Anda.action="/thanks"yang lama dipindahkan ke pengaturan Redirect after submit formulir. - Unduh kiriman lama dari halaman Forms di Netlify terlebih dahulu. Kiriman itu tidak pindah dengan sendirinya.
<form name="contact" netlify hidden>
<input name="name" />
<input name="email" />
<textarea name="message"></textarea>
</form>Biarkan form detection aktif jika formulir lain di situs masih memakai Netlify Forms. Dokumentasi Netlify menyebutkan mematikan deteksi hanya ditujukan untuk situs yang tidak memakai Netlify Forms. Setelah tidak ada yang memakainya, mematikannya menghemat satu pemindaian di setiap deploy.
Pengganti pengaturan spam Netlify
Netlify menjalankan Akismet pada kiriman dan menyediakan netlify-honeypot serta reCAPTCHA. Di Ikiform, honeypot tetap berfungsi jika Anda mengatur Honeypot field formulir ke nama yang sudah Anda pakai, seperti bot-field. Skor spam berjalan di setiap kiriman tanpa setup, dan Spam check yang diatur ke Ikiform menggantikan reCAPTCHA dengan Cloudflare Turnstile tanpa key. Hapus div reCAPTCHA saat Anda beralih.
Formulir React yang mengirim JSON
Tanpa Netlify Forms yang menghalangi, formulir yang dirender di klien tidak butuh duplikat, dan bisa mengirim JSON, yang menjaga tipe data tetap utuh dan memungkinkan Anda merapikan nilai terlebih dahulu. Contoh ini juga mencatat context Netlify mana yang membangun halaman:
import { type FormEvent, useState } from "react";
const ENDPOINT = `https://ikiform.com/f/${import.meta.env.VITE_IKIFORM_FORM_ID}`;
interface Message {
name: string;
email: string;
message: string;
context: string;
}
export function ContactForm() {
const [sent, setSent] = useState(false);
const [error, setError] = useState("");
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const data = new FormData(event.currentTarget);
const body: Message & Record<string, string> = {
name: String(data.get("name") ?? "").trim(),
email: String(data.get("email") ?? "").trim(),
message: String(data.get("message") ?? "").trim(),
context: import.meta.env.VITE_CONTEXT ?? "local",
_gotcha: String(data.get("_gotcha") ?? ""),
};
setError("");
const response = await fetch(ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify(body),
}).catch(() => null);
const result = await response?.json().catch(() => null);
if (result?.ok) return setSent(true);
const fields: Record<string, string[]> = result?.error?.fields ?? {};
setError(Object.values(fields)[0]?.[0] ?? result?.error?.message ?? "Couldn't send. Try again.");
}
if (sent) return <p role="status">Got it. I'll answer from my own inbox, usually the same day.</p>;
return (
<form onSubmit={onSubmit}>
<label htmlFor="name">Name</label>
<input id="name" name="name" autoComplete="name" required />
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email" autoComplete="email" required />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows={6} minLength={10} required />
<input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden />
{error ? <p role="alert">{error}</p> : null}
<button>Send</button>
</form>
);
}Content-Type: application/jsonmemberi tahu Ikiform untuk mem-parsing JSON;Accept: application/jsonmeminta jawaban JSON.VITE_CONTEXTadalah nama contoh. Netlify mengaturCONTEXTsaat build; ekspos ke Vite di perintah build Anda, atau hapus field-nya.- Honeypot dikirim sebagai key JSON. Tetap sertakan di body meskipun inputnya tersembunyi, agar bot yang mengisinya tetap menandai dirinya sendiri.
Deploy preview punya formulir sendiri
Deploy preview berada di host seperti deploy-preview-12--your-site.netlify.app. Itu bukan subdomain dari your-site.netlify.app, jadi tidak cocok di Allowed domains, dan kiriman preview masuk ke spam. Beri preview dan branch deploy formulir sendiri di netlify.toml, dan atur header Content-Security-Policy di file yang sama:
[build]
command = "npm run build"
publish = "dist"
[context.production.environment]
VITE_IKIFORM_FORM_ID = "frm_xxxxxxxxxxxxxxxx"
[context.deploy-preview.environment]
VITE_IKIFORM_FORM_ID = "frm_yyyyyyyyyyyyyyyy"
[context.branch-deploy.environment]
VITE_IKIFORM_FORM_ID = "frm_yyyyyyyyyyyyyyyy"
[[headers]]
for = "/*"
[headers.values]
Content-Security-Policy = "default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.com"Biarkan Allowed domains formulir preview kosong, atau tambahkan host preview persisnya selama pengujian. Formulir production mendapat domain Anda dan your-site.netlify.app. Header di netlify.toml berlaku untuk setiap deploy context; jika Anda lebih suka file _headers, file itu harus berada di publish directory.
netlify.app begitu saja ke Allowed domains. Setiap situs Netlify akan cocok, termasuk salinan formulir Anda di situs orang lain.Pastikan berfungsi
- Buka deploy preview, kirim, dan pastikan pesannya masuk ke formulir preview.
- Merge, lalu kirim di production. Pastikan pesannya masuk ke formulir production dan halaman Forms di Netlify tidak menampilkan yang baru.
- Cek inbox setiap penerima notifikasi. Masing-masing mendapat email berisi field, dan Reply terkirim ke pengirim formulir jika formulir punya field
email. - Kirim dengan honeypot terisi,
_gotcha=bot. Kiriman tetap mendapat jawaban sukses, tetapi disimpan sebagai spam dan tidak memicu email atau webhook. - Tidak ada yang masuk? Ubah filter status di dashboard ke Spam. Spam mendapat jawaban sukses yang sama dengan kiriman asli.
Hal yang sering menjebak
| Masalah | Yang harus dilakukan |
|---|---|
404 saat mengirim | Kiriman masuk ke situs Anda sendiri. Build yang ter-cache mungkin masih punya action lama, atau panggilan fetch masih mengirim ke /. Cari form-name di publish directory. |
| Kiriman masih muncul di Netlify | Ada formulir di halaman yang masih mengirim ke situs Anda sendiri dengan data-netlify atau netlify, jadi Netlify terus mendeteksi dan menyimpannya. Hapus atributnya, atur action ke Ikiform, lalu deploy ulang. |
404 not_found dari Ikiform hanya di preview | Context deploy preview tidak punya VITE_IKIFORM_FORM_ID, jadi URL-nya diakhiri undefined. Tambahkan di bawah [context.deploy-preview.environment]. |
403 origin_not_allowed, atau setiap kiriman masuk ke spam | Domain halaman tidak ada di Allowed domains formulir. Tambahkan, ditambah localhost untuk uji lokal. Subdomain dari domain yang terdaftar diizinkan. |
422 files_not_supported | Formulir punya <input type="file"> dengan file yang dipilih. Upload file belum didukung; hapus input itu atau minta link sebagai gantinya. |
Pertanyaan
Bisa. Netlify hanya menangani formulir yang dideteksinya saat build. Formulir tanpa data-netlify yang action-nya mengarah ke endpoint lain disajikan Netlify seperti halaman biasa dan mengirim langsung ke endpoint itu.
Netlify menjawab POST ke halaman statis dengan 404 kecuali Netlify Forms mendeteksi formulir itu di HTML yang di-deploy. Tandai formulir untuk Netlify Forms atau arahkan action-nya ke backend lain.
Bisa. Deteksi berlaku per formulir, berdasarkan atribut. Pertahankan data-netlify di formulir yang harus ditangani Netlify dan biarkan form detection aktif.
Kiriman itu tetap di Netlify, bukan di Ikiform. Unduh dari halaman Forms situs sebelum Anda mematikan form detection, dan simpan file-nya bersama arsip Anda.
Belum. Kiriman yang berisi file ditolak dengan 422 files_not_supported. Minta link ke file sebagai gantinya, seperti URL shared drive.
Mentok di salah satu langkah, atau ingin panduan untuk situasi Anda? Email hello@ikiform.com.