Formulir pendaftaran newsletter5 menit baca
Formulir pendaftaran email di situs statis, tanpa server
Tambahkan formulir pendaftaran newsletter ke situs statis Hugo, Jekyll, Eleventy, atau Astro, jauhkan API key alat email dari halaman, dan lakukan konfirmasi di alat itu.
Di situs statis, formulir mengirim dari browser pembaca langsung ke Ikiform, karena tidak ada server milik Anda untuk dikirimi. Jauhkan API key alat email Anda dari situs sepenuhnya: browser hanya tahu endpoint Ikiform publik Anda, dan relay yang di-host di tempat lain menambahkan subscriber. Tulis formulir sekali sebagai partial atau include, teruskan source berbeda per penempatan, dan tambahkan satu script kecil untuk versi tanpa reload.
Apa yang berbeda di sini
Situs statis adalah file di sebuah host: GitHub Pages, Netlify, Cloudflare Pages, bucket S3. Tidak ada kode Anda yang berjalan di server saat pembaca mengirim formulir. Itu menutup jalan pintas biasa berupa memanggil API alat email dari halaman, karena apa pun yang dijalankan browser bisa dibaca siapa pun.
API key alat email jarang dibatasi hanya untuk menambahkan satu subscriber. Key yang bisa menambahkan subscriber biasanya juga bisa membaca, mengekspor, atau menghapus seluruh daftar. Taruh di JavaScript situs statis dan key itu terkirim ke setiap pengunjung, dan dari sana ke siapa pun yang membuka developer tools.
- Dengan key di halaman, setiap pengunjung mengunduhnya, dan siapa pun bisa memanggil API alat email dengannya.
- Dengan relay, halaman hanya tahu endpoint Ikiform Anda, yang hanya menerima form post dan tidak lebih.
- Ikiform menyaring spam dan mengirim webhook bertanda tangan ke relay.
- Relay, yang di-host di luar situs statis, memegang API key dan menambahkan subscriber.
Tulis formulirnya sekali
Formulir newsletter muncul di beberapa template: footer, akhir setiap artikel, halaman newsletter. Jadikan partial yang menerima nilai source, agar setiap penempatan mencatat dirinya sendiri. Markup-nya identik di setiap generator; hanya sintaks template untuk source yang berubah.
<form data-newsletter action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<input name="email" type="email" required autocomplete="email" placeholder="you@example.com" aria-label="Email" />
<label><input name="consent" type="checkbox" value="true" required /> Email me the newsletter. I can unsubscribe at any time.</label>
<input type="hidden" name="source" value="{{ .source | default "footer" }}" />
<input type="hidden" name="_redirect" value="https://example.com/subscribed/" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Subscribe</button>
<p role="status" hidden></p>
</form>Lalu taruh di template dengan nama penempatannya:
{{ partial "newsletter.html" (dict "source" "post") }}- Di Astro, gunakan
<Newsletter source="post" />. Build Astro statis tidak bisa menjalankan Actions, jadi komponen mengirim langsung ke Ikiform seperti yang lain. - Tambahkan
sourceke definisi field formulir di Ikiform, sebagai teks dengan panjang maksimum pendek. Setelah field didefinisikan, input yang tidak tercantum di definisi ditolak denganunknown_field. _redirectharus berupa URLhttps:di salah satu Allowed domains formulir. Buat halamannya:/subscribed/dengan baris yang meminta pembaca memeriksa inbox.
Satu script untuk setiap formulir di halaman
Halaman artikel bisa punya dua formulir newsletter, satu setelah artikel dan satu di footer. Script ini menangani setiap formulir bertanda data-newsletter, dan saat satu berhasil, script mengganti semuanya, jadi tidak ada yang diminta berlangganan lagi beberapa senti di bawahnya. Muat sekali dari base layout Anda.
for (const form of document.querySelectorAll("form[data-newsletter]")) {
const status = form.querySelector('[role="status"]');
const button = form.querySelector("button");
form.addEventListener("submit", async (event) => {
event.preventDefault();
button.disabled = true;
status.hidden = false;
status.textContent = "Subscribing";
try {
const response = await fetch(form.action, {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
const result = await response.json();
if (result.ok) {
for (const other of document.querySelectorAll("form[data-newsletter]")) {
other.replaceChildren(Object.assign(document.createElement("p"), {
textContent: "Almost done. Check your inbox for a confirmation link.",
}));
}
return;
}
if (response.status === 429 && response.headers.has("Retry-After")) {
status.textContent = "Too many tries from this network. Wait a minute and try again.";
} else {
const errors = result.error.fields ?? {};
status.textContent = errors.email?.[0] ?? errors.consent?.[0] ?? result.error.message;
}
} catch {
form.submit();
return;
}
button.disabled = false;
});
}- Jika
fetchgagal, misalnya di balik filter jaringan yang ketat, script kembali keform.submit(), yang mengirim dengan cara biasa dan mendarat di/subscribed/. 429punya pesannya sendiri. Pembaca di satu jaringan kantor atau kampus berbagi IP dan bisa mencapai batas per pengunjung bersama-sama.- Formulir bekerja saat JavaScript mati. Script hanya mengubah cara jawaban ditampilkan.
Pembaca dengan JavaScript mati mendarat di /subscribed/, jadi buat halaman itu melakukan apa yang dilakukan script untuk semua orang lain: menyatakan email konfirmasi sedang dalam perjalanan, menyebut nama pengirim yang perlu dicari, menyinggung folder spam, dan menautkan kembali ke blog. Itu halaman biasa di generator Anda, dibuat seperti halaman lainnya, dan juga tempat Anda bisa mengarahkan tautan konfirmasi alat email nantinya.
Di mana relay berada
Relay butuh URL HTTPS publik yang menjalankan kode. Host statis Anda mungkin menyediakannya, mungkin juga tidak:
| Host statis | Opsi relay |
|---|---|
| GitHub Pages, S3 | Tanpa function. Gunakan Cloudflare Worker di domain kustom, atau alat otomasi |
| Netlify | Netlify Function di domain situs Anda, atau salah satu opsi di atas |
| Cloudflare Pages | Worker terpisah di domain kustom. Ikiform menolak URL pages.dev dan workers.dev |
| Vercel | Function di domain Anda. Output statis bisa berdampingan dengan route API |
Kode relay untuk setiap alat email ada di halaman Kit, MailerLite, dan beehiiv. Tanpa kode sama sekali, arahkan webhook ke Zapier atau n8n dan gunakan action alat email mereka. Dokumentasi webhook mendaftar aturan URL-nya.
localhost.Jika situs Anda mengirim Content Security Policy
Banyak host statis memungkinkan Anda mengatur header dari file, seperti _headers di Netlify dan Cloudflare Pages. Jika situs Anda mengirim Content-Security-Policy, browser memblokir formulir kecuali kebijakannya mengizinkan Ikiform. form-action mencakup kiriman biasa dan connect-src mencakup fetch milik script:
Content-Security-Policy: default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.comKiriman yang diblokir muncul sebagai error CSP di konsol browser dan tidak pernah sampai ke Ikiform, jadi tidak ada yang muncul di dashboard juga.
Pastikan berfungsi
- Tambahkan domain live Anda dan
localhostdi Allowed domains. - Build situs dan buka halaman artikel. Kedua formulir ada di sana, masing-masing dengan nilai
sourcesendiri di source halaman. - Berlangganan dari formulir artikel dengan alamat milik Anda. Kedua formulir berubah menjadi baris periksa-inbox.
- Matikan JavaScript dan berlangganan dari footer. Anda mendarat di
/subscribed/. - Buka Submissions di dashboard. Kedua pendaftaran menampilkan
postdanfootersebagaisource-nya. - Cari API key alat email Anda di situs hasil build. Key itu tidak ada di sana.
Hal yang sering menjebak
| Masalah | Yang harus dilakukan |
|---|---|
| Tidak ada apa-apa di dashboard, dan ada error CSP di konsol | Tambahkan https://ikiform.com ke form-action dan connect-src di Content-Security-Policy Anda. |
422 dengan unknown_field untuk source | Tambahkan source ke definisi field formulir, atau hapus input tersembunyinya. |
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. |
| Browser mendarat di halaman terima kasih Ikiform, bukan halaman Anda | _redirect diabaikan kecuali domainnya ada di Allowed domains dan berupa URL https:. Tambahkan domainnya, atau atur Redirect after submit di pengaturan formulir sebagai gantinya. |
Pertanyaan
Bisa. Formulir mengirim dari browser ke backend formulir seperti Ikiform, yang menyimpan dan menyaring setiap pendaftaran. Relay atau alat otomasi yang di-host di tempat lain meneruskannya ke alat email Anda, jadi situs statisnya sendiri tidak menjalankan kode server.
Jangan. Key apa pun di JavaScript halaman terlihat oleh setiap pengunjung, dan key alat email biasanya bisa membaca atau mengubah seluruh daftar. Simpan key di relay yang berjalan di luar situs.
Ya. Formulirnya HTML biasa dan mengirim ke Ikiform. GitHub Pages tidak bisa menjalankan relay, jadi host relay di Cloudflare Worker dengan domain kustom, atau gunakan alat otomasi seperti Zapier atau n8n.
Alat email Anda. Ikiform tidak pernah mengirim email ke orang yang mendaftar. Relay menambahkan pembaca sebagai belum terkonfirmasi dan alat itu mengirim tautan konfirmasinya sendiri.
Mentok di salah satu langkah, atau ingin panduan untuk situasi Anda? Email hello@ikiform.com.