# Ikiform Guides

> How-to guides for collecting form submissions on any site: waitlists, contact forms, spam, email and webhooks, with code you can copy.

## [How to create a waitlist for a new SaaS](https://ikiform.com/guides/waitlist.md)

Build a pre-launch waitlist on your own landing page: the form, spam protection, duplicates, confirmation emails and a clean export on launch day.

- [How to build a pre-launch email list for a Product Hunt launch](https://ikiform.com/guides/waitlist/product-hunt.md): Collect a launch list weeks before Product Hunt, tag each signup by channel, and send the launch-day email in two waves timed to the Pacific Time reset.
- [How to build a beta signup form that screens applicants](https://ikiform.com/guides/waitlist/beta-signup.md): A beta application form with screening questions the server enforces, and a script that scores applicants and picks each cohort from the list.
- [How to build a waitlist page for a mobile app before App Store launch](https://ikiform.com/guides/waitlist/mobile-app.md): A pre-launch waitlist for an iOS or Android app that asks which phone people use, sends iPhone testers to TestFlight and fills a Play closed test.
- [How to build a Next.js waitlist with a server action](https://ikiform.com/guides/waitlist/nextjs.md): A Next.js App Router waitlist: a server action that forwards signups with a secret key, useActionState, an optimistic thank-you and a per-visitor limit.
- [How to add a waitlist to a Framer site](https://ikiform.com/guides/waitlist/framer.md): Two ways to collect waitlist signups on Framer: Framer's form with a webhook to Ikiform, or a code component that keeps per-visitor limits and spam checks.
- [How to add a waitlist form to a Webflow site](https://ikiform.com/guides/waitlist/webflow.md): Point a Webflow Form Block at Ikiform, tag signups by source with a hidden field, and keep Webflow's success state with a short script for every form.
- [How to add a waitlist to a Carrd site](https://ikiform.com/guides/waitlist/carrd.md): Collect waitlist signups on a Carrd page: a Send to URL form on Pro Plus with UTM tracking, or an embedded HTML form with a honeypot on Pro Standard.
- [How to add a waitlist form in plain HTML to any landing page](https://ikiform.com/guides/waitlist/html.md): A complete no-build waitlist page in plain HTML that works with JavaScript off, shows an inline thank-you when it loads, and falls back when it must.
- [Build a waitlist in Astro](https://ikiform.com/guides/waitlist/astro.md): An Astro waitlist on a static landing page: an Action forwards each signup, a script calls it, and one on-demand page catches posts without JavaScript.
- [Build a waitlist in TanStack Start](https://ikiform.com/guides/waitlist/tanstack-start.md): A TanStack Start waitlist: one server route answers both a plain form post and fetch, and validateSearch carries the source and the result in the URL.
- [Build a waitlist in React Router](https://ikiform.com/guides/waitlist/react-router.md): A React Router waitlist in the footer of every page: a fetcher posts to one route action, tags each signup with its page and works without JavaScript.
- [Build a waitlist in SvelteKit](https://ikiform.com/guides/waitlist/sveltekit.md): A SvelteKit 3 waitlist: a hook keeps the first ?ref= in a cookie, a named form action forwards the signup, and returning visitors see they joined.
- [Build a waitlist in Nuxt](https://ikiform.com/guides/waitlist/nuxt.md): A Nuxt waitlist on a prerendered landing page: one Nitro route takes $fetch and plain form posts, checks them with Zod and redirects without JavaScript.

## [Add a contact form to a static site without a backend](https://ikiform.com/guides/contact-form-static-site.md)

Add a working contact form to a static site with no server: where the POST goes, spam, replies by email, and code for every host and framework.

- [Add a contact form to a GitHub Pages site](https://ikiform.com/guides/contact-form-static-site/github-pages.md): GitHub Pages can't run server code, so a form POST gets 405 Not Allowed; post to a form backend instead and get project-site redirects right.
- [Fix the 405 error on a contact form hosted on Vercel](https://ikiform.com/guides/contact-form-static-site/vercel.md): A static page on Vercel answers a form POST with 405 Method Not Allowed; here is why, and how to send the form to a backend instead.
- [Add a contact form on Netlify without Netlify Forms](https://ikiform.com/guides/contact-form-static-site/netlify.md): Run a contact form on a Netlify site without Netlify Forms: no build-time detection, JSON posts from React, and a separate form for deploy previews.
- [Add a contact form to a Cloudflare Pages site](https://ikiform.com/guides/contact-form-static-site/cloudflare-pages.md): Add a contact form to Cloudflare Pages without writing a Function: post to a form backend, set headers in _headers and use your own Turnstile keys.
- [Add a contact form to an Amazon S3 static website](https://ikiform.com/guides/contact-form-static-site/aws-s3.md): S3 website endpoints accept only GET and HEAD over plain HTTP, so post the contact form to a form backend and get redirects right with CloudFront.
- [Add a contact form to your portfolio website](https://ikiform.com/guides/contact-form-static-site/portfolio-website.md): A portfolio contact form that asks the questions you'd ask on a first call: project, budget, timing and a link, with no server and replies from your inbox.

## [Send HTML form submissions to your email](https://ikiform.com/guides/send-form-to-email.md)

Get every form submission in your inbox without a mail server: why mailto: and PHP mail() fail, and a setup that filters spam and lets you reply.

- [Send an HTML form to email without PHP](https://ikiform.com/guides/send-form-to-email/without-php.md): Replace a contact.php script that calls mail() with a form that posts to a hosted endpoint, keeping your field names, your thank-you page and replies.
- [Send a website form to Gmail (and why mailto: fails)](https://ikiform.com/guides/send-form-to-email/gmail.md): Get form submissions in Gmail without mailto: links, app passwords or Apps Script, then label them, keep them out of spam and reply from Gmail.
- [Send one form to several email addresses](https://ikiform.com/guides/send-form-to-email/multiple-recipients.md): Email one form to your whole team, or route each message to the right person by topic, without letting the form itself pick who gets the mail.
- [Reply to form submissions straight from your inbox](https://ikiform.com/guides/send-form-to-email/reply-to.md): Make Reply on a form notification write to the person who filled in the form: which field names work, when to use _replyto, and why replies go astray.
- [An EmailJS alternative that keeps keys off the client](https://ikiform.com/guides/send-form-to-email/emailjs-alternative.md): Move a contact form off EmailJS: why browser-side email keys are a risk, what changes in your code, and what you give up, such as the auto-reply.
- [A Next.js contact form that sends email](https://ikiform.com/guides/send-form-to-email/nextjs.md): Two ways to email a Next.js form with a Server Action: send it yourself with Resend or Nodemailer, or forward it to a form backend, compared honestly.

## [How to stop contact form spam](https://ikiform.com/guides/spam-protection.md)

Stop contact form spam with layers that cost real people nothing: a honeypot, timing, content scoring, rate limits and a human check only where needed.

- [How to add a honeypot field that bots fill and people don't](https://ikiform.com/guides/spam-protection/honeypot.md): Add a honeypot to any form that catches bots without tripping screen readers, keyboards or autofill, with the server check for every stack.
- [How to add Cloudflare Turnstile to an HTML form](https://ikiform.com/guides/spam-protection/cloudflare-turnstile.md): Add Cloudflare Turnstile to a plain HTML form: the widget, server-side siteverify, test keys, and a way to run it with no keys or server of your own.
- [How to stop form spam without a captcha](https://ikiform.com/guides/spam-protection/without-captcha.md): Stop most form spam with no captcha at all: a honeypot, a signed render time, a content score and a rate limit, added together instead of used alone.
- [reCAPTCHA alternatives for website forms](https://ikiform.com/guides/spam-protection/recaptcha-alternatives.md): Compare reCAPTCHA alternatives for forms, from Turnstile and hCaptcha to proof-of-work and no captcha at all, then switch with a small, safe change.
- [How to rate limit form submissions](https://ikiform.com/guides/spam-protection/rate-limiting.md): Rate limit form submissions per visitor with a shared store, answer 429 with Retry-After, and avoid locking out offices that share one IP.
- [How to stop spam on a static site contact form](https://ikiform.com/guides/spam-protection/static-site.md): Stop spam on a static site form even though it can't keep a secret or count posts, with a honeypot partial, a safe script and server-side checks.
- [How to stop Webflow form spam](https://ikiform.com/guides/spam-protection/webflow.md): Protect a Webflow form that posts to a form backend, where Webflow's own spam settings never run, with an off-screen honeypot and a human check.
- [Next.js form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/nextjs.md): Protect a Next.js form from spam: a honeypot, Turnstile checked in a server action, a per-IP limit on Vercel, Netlify or Cloudflare, and a CSP for it.
- [Astro form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/astro.md): Protect an Astro form from spam with an Action: a honeypot, Turnstile checked with astro:env secrets, a per-IP limit and Astro's built-in CSP.
- [TanStack Start form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/tanstack-start.md): Protect a TanStack Start form from spam: function middleware for the client IP, a token bucket, Turnstile verified in a server function, and a CSP.
- [React Router form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/react-router.md): Protect a React Router form from spam: a route action with Turnstile, a Workers rate limit keyed on cf-connecting-ip, a .server module and a CSP header.
- [SvelteKit form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/sveltekit.md): Protect a SvelteKit form from spam: a form action with getClientAddress, a per-IP limit, Turnstile behind use:enhance, and a CSP that allows it.
- [Nuxt form spam protection with Turnstile](https://ikiform.com/guides/spam-protection/nuxt.md): Protect a Nuxt form from spam: a Nitro server route with Turnstile, a per-IP limit in Nitro storage, runtimeConfig secrets and a CSP set in routeRules.

## [Outgrow your website builder's forms](https://ikiform.com/guides/website-builder-forms.md)

When Webflow, Netlify, Carrd or Framer forms hit a cap or a missing feature, keep the form you designed and point it at a form backend instead.

- [Webflow form submission limit: what it is and how to get past it](https://ikiform.com/guides/website-builder-forms/webflow-submission-limit.md): Webflow's free Starter plan stops collecting after 50 form submissions per site and exported sites get none, so point the Form Block at Ikiform instead.
- [Netlify Forms limit: what happens at 100 submissions, and the way out](https://ikiform.com/guides/website-builder-forms/netlify-forms-limit.md): Legacy Netlify plans meter form submissions per site and upgrade you automatically, and credit plans can pause the site, so move the form to a backend.
- [Carrd forms: send submissions to a form backend](https://ikiform.com/guides/website-builder-forms/carrd-forms.md): Carrd's contact form only emails you and custom forms need Pro Plus, so use Send to URL on Plus or an HTML embed on Standard to store every submission.
- [Framer forms: when to add a form backend, and how](https://ikiform.com/guides/website-builder-forms/framer-forms.md): Framer forms already send to email, Sheets or a webhook; add Ikiform as the webhook for stored, filtered submissions, team alerts and more destinations.

## [Add a feedback form to your website or app](https://ikiform.com/guides/feedback-form.md)

Put a feedback form on any page or inside your app: a rating, a comment, the page it came from, spam filtering, and alerts when a score is low.

- [Add a bug report form that captures the page, browser and steps](https://ikiform.com/guides/feedback-form/bug-report.md): A bug report form that asks people for steps and severity, and lets the page add the URL, browser, viewport and recent errors on its own.
- [Collect feature requests you can count, rank and answer](https://ikiform.com/guides/feedback-form/feature-request.md): A feature request form that asks for the problem instead of the solution, stores requests by theme, counts people not rows, and emails them when it ships.
- [Build a floating feedback widget for your React app](https://ikiform.com/guides/feedback-form/react-feedback-widget.md): A floating feedback button for a React app that opens a small panel, sends the screen, app version and account with each answer, and never loses a draft.
- [Collect beta tester feedback build by build](https://ikiform.com/guides/feedback-form/beta-tester-feedback.md): A beta feedback form with a personal link per tester and build, two rating scales and a weekly summary that shows whether each build got better.
- [Run an NPS survey on your own site, from email link to score](https://ikiform.com/guides/feedback-form/nps-survey.md): Run an NPS survey with a 0 to 10 score in the email, a follow-up question on your own page that changes with the score, and a script that calculates NPS.
- [Add a cancellation survey to your SaaS cancel flow](https://ikiform.com/guides/feedback-form/cancellation-survey.md): Ask why customers cancel inside your SaaS cancel flow, keep Skip one click away, save the reason to Stripe and Ikiform, and never delay the cancel.
- [Build an in-app feedback form in Next.js](https://ikiform.com/guides/feedback-form/nextjs.md): An in-app Next.js feedback form: a server action that reads the session, takes the page from the request and forwards a rating with the user attached.
- [Build an in-app feedback form in Astro](https://ikiform.com/guides/feedback-form/astro.md): An in-app Astro feedback form: an action that takes the user from middleware locals, the page from the request and the screen from the route pattern.
- [Build an in-app feedback form in TanStack Start](https://ikiform.com/guides/feedback-form/tanstack-start.md): An in-app TanStack Start feedback form: a POST server function with session middleware, the route id as context, and the page read from request headers.
- [Build an in-app feedback form with React Router](https://ikiform.com/guides/feedback-form/react-router.md): A React Router 8 feedback form: a resource route action reads the cookie session, a fetcher posts from the layout, and a no-JS post redirects back.
- [Build an in-app feedback form in SvelteKit](https://ikiform.com/guides/feedback-form/sveltekit.md): An in-app SvelteKit feedback form: a layout form posts to one form action, which adds the user from locals and the page from the request on the server.
- [Build an in-app feedback form in Nuxt](https://ikiform.com/guides/feedback-form/nuxt.md): An in-app Nuxt feedback form: a server route that reads the user session, takes the page from Referer and still works when JavaScript hasn't loaded.

## [Build a lead capture form that reaches you fast](https://ikiform.com/guides/lead-capture.md)

A lead capture form on your own site that emails you with reply-to, pings team chat and feeds your CRM, so you answer while the lead is still there.

- [Build a demo request form that books the call](https://ikiform.com/guides/lead-capture/demo-request.md): A book-a-demo form that stores the lead, then sends the visitor to Cal.com or Calendly with their name and email already filled in.
- [Build a quote request form without file uploads](https://ikiform.com/guides/lead-capture/quote-request.md): A request-a-quote form that collects briefs as shared links instead of uploads, puts a due date on every request, and keeps link-heavy leads out of spam.
- [Build a consultation request form for a service business](https://ikiform.com/guides/lead-capture/consultation-request.md): A consultation request form for accountants, lawyers, coaches and clinics that asks how and when to call, and leaves sensitive details for the call.
- [Build a project inquiry form for an agency or freelancer](https://ikiform.com/guides/lead-capture/project-inquiry.md): A start-a-project form for studios and freelancers that sorts inquiries into hot, warm and no-fit by budget and timing before anyone reads the brief.
- [Send form leads to HubSpot or Pipedrive](https://ikiform.com/guides/lead-capture/leads-to-crm.md): Map each signed Ikiform webhook to HubSpot's contact upsert or Pipedrive's person and lead calls, without duplicate contacts when a delivery is retried.
- [Build a qualifying lead form in Next.js](https://ikiform.com/guides/lead-capture/nextjs.md): A Next.js App Router lead form that validates with Zod in a server action, keeps first-touch UTMs in a cookie and sends qualified leads to your calendar.
- [Build a qualifying lead form in Astro](https://ikiform.com/guides/lead-capture/astro.md): An Astro lead form built on Actions: Zod validation, first-touch UTMs on a static site, an on-demand contact page and a redirect to your scheduler.
- [Build a qualifying lead form in TanStack Start](https://ikiform.com/guides/lead-capture/tanstack-start.md): A TanStack Start lead form: global request middleware for first-touch UTMs, a server function with Zod, and a thrown redirect to your scheduler.
- [Build a qualifying lead form in React Router](https://ikiform.com/guides/lead-capture/react-router.md): A React Router framework-mode lead form: root middleware with a signed first-touch cookie, a route action that validates, and a redirect to your scheduler.
- [Build a qualifying lead form in SvelteKit](https://ikiform.com/guides/lead-capture/sveltekit.md): A SvelteKit lead form: the handle hook records first-touch UTMs, a form action validates with Valibot, and redirect() sends qualified leads to a calendar.
- [Build a qualifying lead form in Nuxt](https://ikiform.com/guides/lead-capture/nuxt.md): A Nuxt lead form: server middleware records first-touch UTMs, one Zod-validated server route serves fetch and plain posts, and good leads book a call.

## [Newsletter signup form without Mailchimp's embed](https://ikiform.com/guides/newsletter-signup.md)

Build a newsletter signup form in your own markup, record consent, block bot signups and pass each subscriber to Kit, MailerLite, beehiiv or any tool.

- [Double opt-in for a newsletter form you built yourself](https://ikiform.com/guides/newsletter-signup/double-opt-in.md): Ikiform doesn't send confirmation emails, so double opt-in runs in your email tool: a relay adds each signup as unconfirmed and the tool sends the link.
- [Email signup form on a static site, with no server](https://ikiform.com/guides/newsletter-signup/static-site.md): Add a newsletter signup form to a Hugo, Jekyll, Eleventy or Astro static site, keep the email tool's API key out of the page and confirm in the tool.
- [Send your own newsletter form's signups to Kit](https://ikiform.com/guides/newsletter-signup/kit.md): Connect your own newsletter form to Kit with a relay that creates the subscriber, adds them to a Kit form for the incentive email, and tags the placement.
- [Send your own newsletter form's signups to MailerLite](https://ikiform.com/guides/newsletter-signup/mailerlite.md): Connect your own signup form to MailerLite: a relay adds new readers as unconfirmed for double opt-in and never asks a subscriber to confirm twice.
- [Send your own newsletter form's signups to beehiiv](https://ikiform.com/guides/newsletter-signup/beehiiv.md): Connect your own signup form to beehiiv: a relay creates each subscription with double opt-in on, the placement as UTM source and the page as referrer.
- [Build a newsletter signup form in Next.js](https://ikiform.com/guides/newsletter-signup/nextjs.md): A Next.js footer newsletter form: a server action with a consent check and Turnstile, posting to Ikiform, plus a route handler that adds readers to Kit.
- [Build a newsletter signup form in Astro](https://ikiform.com/guides/newsletter-signup/astro.md): An Astro newsletter form that stays on prerendered pages: an Astro Action checks consent, posts to Ikiform, and an endpoint adds readers to MailerLite.
- [Build a newsletter signup form in TanStack Start](https://ikiform.com/guides/newsletter-signup/tanstack-start.md): A TanStack Start newsletter form: a server function for in-page signups, a server route as the no-JavaScript fallback, and real signups sent to beehiiv.
- [Build a newsletter signup form in React Router](https://ikiform.com/guides/newsletter-signup/react-router.md): A React Router footer newsletter form: useFetcher posts to a /newsletter route that also works without JavaScript, and a resource route feeds MailerLite.
- [Build a newsletter signup form in SvelteKit](https://ikiform.com/guides/newsletter-signup/sveltekit.md): A SvelteKit 3 newsletter form in the layout: a form action with consent and an IP limit, use:enhance that stays on the page, and a Kit webhook route.
- [Build a newsletter signup form in Nuxt](https://ikiform.com/guides/newsletter-signup/nuxt.md): A Nuxt newsletter form that works with or without JavaScript: a server route with a Turnstile check posts to Ikiform, and a Nitro route feeds beehiiv.

## [How HTML form submission works](https://ikiform.com/guides/html-form-submission.md)

What a browser does when a form is submitted: which fields it sends, how it encodes them, what the server should answer, and how Ikiform answers.

- [Submit an HTML form without a page reload](https://ikiform.com/guides/html-form-submission/without-page-reload.md): Send a form with fetch and FormData so the visitor stays on the page, with field errors, a loading state, retries and a fallback when scripts fail.
- [Redirect to a thank-you page after form submit](https://ikiform.com/guides/html-form-submission/redirect-after-submit.md): Send visitors to your own thank-you page after a form posts: the 303 redirect, the _redirect field, which domains are allowed and what refresh does.
- [The HTML form action attribute, explained](https://ikiform.com/guides/html-form-submission/action-attribute.md): What a form's action attribute does, how relative and empty values resolve, how formaction sends one form to two places, and why static hosts answer 405.
- [HTML form validation in the browser and on the server](https://ikiform.com/guides/html-form-submission/validation.md): Validate a form with required, type, pattern and min, style errors with :user-invalid, and enforce the same rules on the server with field definitions.

## [Event registration and RSVP forms on your own site](https://ikiform.com/guides/event-registration.md)

Take RSVPs on your own event page: the form, guest limits, an honest headcount, closing when full and a check-in list, without a ticketing app.

- [Wedding RSVP form on your own wedding website](https://ikiform.com/guides/event-registration/wedding-rsvp.md): An RSVP form for a wedding website you built yourself: one reply per invitation, a meal per named guest, a deadline and a list of who hasn't replied.
- [Event registration without Eventbrite, for free community events](https://ikiform.com/guides/event-registration/without-eventbrite.md): Run registration for a free community event on your own site: session choices, a confirmation email from your own tool, room counts and a check-in list.
- [Volunteer signup form with shifts, for events and festivals](https://ikiform.com/guides/event-registration/volunteer-signup.md): A volunteer signup form where people pick shifts, with a phone number for the day, and a script that shows which shifts are short and builds the rota.

## [Verify form webhook signatures](https://ikiform.com/guides/webhook-signature-verification.md)

Check that a form webhook really came from Ikiform: the Standard Webhooks HMAC-SHA256 scheme, a test vector, raw bodies, timestamps and secret rotation.

- [Verify webhook signatures in Node.js](https://ikiform.com/guides/webhook-signature-verification/nodejs.md): Verify Ikiform webhook signatures in Node.js: raw bodies in Express and Fastify, the SDK, the standardwebhooks package and a tested node:crypto version.
- [Verify webhook signatures in Python](https://ikiform.com/guides/webhook-signature-verification/python.md): Verify Ikiform webhook signatures in Flask, FastAPI and Django, with the standardwebhooks package or the standard library, plus a pytest test.
- [Verify webhook signatures in Go](https://ikiform.com/guides/webhook-signature-verification/go.md): Verify Ikiform webhook signatures in Go with net/http: read the body once, check it with crypto/hmac, test it, or use the Standard Webhooks library.
- [Verify webhook signatures in PHP and Laravel](https://ikiform.com/guides/webhook-signature-verification/php.md): Verify Ikiform webhook signatures in plain PHP with hash_hmac and hash_equals, and in Laravel with the Standard Webhooks library and a CSRF exception.
- [Verify webhook signatures in Ruby and Rails](https://ikiform.com/guides/webhook-signature-verification/ruby.md): Verify Ikiform webhook signatures in Sinatra with OpenSSL and a Minitest test, and in Rails with the standardwebhooks gem and request.raw_post.
