splitforms.com
← Back to the journal

Netlify Contact Form Without Netlify Forms or Functions (2026)

Add a Netlify contact form without Netlify Forms or Functions. Use a hosted endpoint for email, spam filtering, a dashboard, and 500 free submissions total.

Start free — 500 submissionsSee pricing →No card, no time limit. Pro is $5 per month.
Short answer

Skip Netlify Forms when you need to avoid host lock-in, and skip Netlify Functions when you do not want to maintain backend code. Point your form's action at splitforms.com/api/submit, add a hidden access_key input, and your Netlify-hosted page gets 500 free submissions total with real spam filtering, dashboard capture, owner email delivery, and signed webhooks on paid plans (from $5/month) when you need automation.

Try it on your own form

Point any HTML form at one endpoint. 500 free submissions — no card, no time limit — and unlimited forms.

Create free account

Moving hosting too? Follow our Netlify Forms to Cloudflare Pages migration checklist for before/after HTML, historical exports and a reversible cutover.

Why not just use Netlify Forms?

Netlify Forms ships with every Netlify-hosted site. Add data-netlify="true" to a form, deploy, and Netlify intercepts the POST during build to wire it through their backend. Zero configuration, zero JavaScript. For a personal site getting ten contact-form submissions a month, that's a legitimate solution.

Submission price is no longer the issue. The trade-offs are elsewhere:

  • Price: free on current plans, capped on legacy ones. Netlify's credit-based plans (every account created since September 4, 2025) no longer meter form submissions. Legacy plans keep their separate limit of 100 submissions per site per month; splitforms instead gives you a hosting-independent allowance.
  • Host lock-in. Your forms only work while the site is on Netlify. Moving to Vercel, Cloudflare Pages, or your own infra means rewriting form handling.
  • Fixed spam tooling. Akismet runs server-side; flagged submissions go to a Spam submissions list you can review, mark as verified and read through the API. The only extra layers are a honeypot and reCAPTCHA 2, and Netlify's docs describe no way to tune the Akismet filter itself. splitforms's rule-based spam scoring gives you per-submission spam scores and a separate searchable spam folder.
  • No documented re-delivery. Netlify keeps submissions in the Forms tab, with CSV export and an API, so nothing is lost, but its notification docs describe no way to re-send a missed email or webhook. splitforms stores every submission in the dashboard first, lets you re-send a missed notification email, and logs each signed webhook delivery (with one automatic retry) so you can see what failed.
  • Webhook signing is undocumented. Netlify's form notification docs describe outgoing webhooks but no signature scheme, so check what you can verify on your end. On paid plans splitforms signs every webhook with HMAC-SHA256 so you can verify authenticity in 5 lines of server code.

For a production contact form that has to survive a host move, or where missing a lead has real cost, an external backend is the safer pick. If the site will stay on Netlify, the built-in option is a reasonable choice.

The complete migration, in one snippet

Open your existing Netlify Forms-wired contact form. It probably looks like this:

<!-- BEFORE — Netlify Forms wiring -->
<form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field">
  <input type="hidden" name="form-name" value="contact" />
  <p hidden><label>Don't fill: <input name="bot-field" /></label></p>
  <p><label>Name <input name="name" required /></label></p>
  <p><label>Email <input name="email" type="email" required /></label></p>
  <p><label>Message <textarea name="message" required></textarea></label></p>
  <p><button type="submit">Send</button></p>
</form>

Replace it with the splitforms version:

<!-- AFTER — splitforms wiring -->
<form action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input type="hidden" name="redirect"   value="https://yoursite.netlify.app/thanks" />

  <label>Name<input name="name" required /></label>
  <label>Email<input name="email" type="email" required /></label>
  <label>Message<textarea name="message" required></textarea></label>

  <!-- Honeypot — splitforms recognizes 'botcheck' as a spam trap -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" />

  <button type="submit">Send</button>
</form>

The notable removals: data-netlify="true", netlify-honeypot="bot-field", and the hidden form-name input. Those are Netlify Forms-specific attributes; leaving them in while pointing at splitforms creates confusing double-handling at build time (Netlify still tries to register the form even though it'll never receive submissions).

Get your splitforms access key

Sign up at splitforms.com with your email. Your access key is created instantly and is visible in the dashboard. Paste it into the hidden access_key input on your contact form. The free tier covers 500 submissions in total (a one-time allowance, not monthly), unlimited forms, no credit card.

Custom thank-you page

By default, splitforms shows a generic thank-you page after a successful submission. To send visitors to your own page, add a redirect hidden input:

<input type="hidden" name="redirect" value="https://yoursite.netlify.app/thanks" />

On a Netlify-hosted Astro / Eleventy / Hugo site, create the thanks.html (or thanks/index.html) page and Netlify serves it natively. No build-step changes needed.

Inline success without a page reload

The native form submission shows the thank-you page on a new navigation. For inline success states (no page reload), intercept the submit event with JavaScript:

<form id="contact">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" />
  <button type="submit">Send</button>
</form>
<p id="status"></p>

<script>
const form = document.getElementById("contact");
const status = document.getElementById("status");
form.addEventListener("submit", async (e) => {
  e.preventDefault();
  status.textContent = "Sending…";
  try {
    const res = await fetch("https://splitforms.com/api/submit", {
      method: "POST",
      body: new FormData(form),
    });
    const data = await res.json();
    status.textContent = data.success ? "Thanks!" : (data.message || "Error.");
    if (data.success) form.reset();
  } catch {
    status.textContent = "Network error.";
  }
});
</script>

Works in any Netlify-hosted site, no Functions, no SSR adapter. See the AJAX guide for the four-state UI version.

Testing on a Netlify deploy preview

Push the migration to a branch and let Netlify build the deploy preview. Submit a test entry from the preview URL — the email arrives in your inbox within seconds and the submission appears in the splitforms dashboard. If you see the submission, the wiring is correct.

If the form doesn't submit at all, the most common cause is stale Netlify Forms wiring (a hidden form-name input or data-netlify="true" still in the markup). Strip them all and redeploy.

When Netlify Forms is still the right call

Two cases. (1) Sites already committed to Netlify that benefit from its free, unlimited submissions on current credit plans. (2) Compliance contexts where the data must stay inside Netlify's infrastructure for procurement or audit reasons. Choose a standalone backend when hosting portability matters more.

Add a contact form to another platform

Site builders:
Frameworks:
Static site generators:

See also

FAQ

What's wrong with Netlify Forms?
Nothing inherently — current Netlify credit plans include free, unlimited form submissions. The trade-offs are host lock-in, build-time form detection, URL-encoded-only AJAX, an 8 MB request limit, and a fixed Akismet filter with a honeypot and reCAPTCHA 2 as the only extras. A standalone backend is useful when portability or independent operations matter.
Do I need to remove data-netlify="true" to use splitforms?
Yes. The data-netlify="true" attribute (and the <input type="hidden" name="form-name"> companion) tell Netlify's build pipeline to route the form through Netlify Forms. If you leave them in while pointing the action at splitforms, you'll get confusing double-handling. Strip both, set action="https://splitforms.com/api/submit", add the splitforms access_key hidden input, and you're done.
Will my site still work if I switch from Netlify Forms to splitforms?
Yes. The form HTML is the same shape — name/email/message inputs, a submit button. Only the action URL and the access_key field change. Visitors won't notice; you'll get the submissions via email and the splitforms dashboard instead of the Netlify dashboard. Existing inbound links to your contact page keep working.
Can I keep using Netlify Forms for some forms and splitforms for others?
Yes, but it's confusing to maintain. Pick one backend per form and stick with it. The pragmatic move is to migrate every form to splitforms — same backend, same dashboard, same webhooks for all of them. Splitting forms across two services means two dashboards, two spam queues and two sets of notification settings.
Does this require a Netlify Function?
No. The form POSTs directly from the static page to splitforms.com — no Netlify Function in between. Form handling uses none of your Netlify Functions usage, so it stays available for code that needs a server. That matters most on legacy plans, where Netlify lists 125k function invocations per site per month on Free, Starter and Pro; credit-based plans charge function compute in credits instead.
What about Netlify's built-in spam filtering (Akismet)?
Netlify Forms checks every submission with Akismet. Flagged ones go to a Spam submissions list that you can review, move back to verified with Mark as verified, or pull through the Netlify API; a honeypot and reCAPTCHA 2 are opt-in extras, and submissions they catch are rejected without being kept. splitforms uses rule-based spam scoring on top of a honeypot and a time-trap, so you can review flagged submissions in the dashboard, see why each was flagged and recover any false positive in one click.

Related articles

More practical guidance from tutorials.

Browse the journal →
Tutorials

How to Remove the Arrows From a Number Input (CSS, Tailwind, React)

Hide the number input spin buttons with ::-webkit-inner-spin-button and appearance: textfiel…

7 min readRead →
Tutorials

How to Change the Autofill Background Color of an Input (CSS, Tailwind)

Remove Chrome's yellow autofill background with input:-webkit-autofill, inset box-shadow, -w…

7 min readRead →
Tutorials

input type=number maxlength Not Working? 4 Fixes That Work

Why maxlength is ignored on input type=number, plus four fixes: min/max, oninput slice, text…

8 min readRead →

Explore this topic

Start with the overview, then move into focused guides.

OverviewWhat Is a Form Backend? (Complete Guide)Start here →GuideSelf-Hosted vs SaaS Form BackendRead →GuideForm Backend vs Form BuilderRead →GuideWhere Do Form Submissions Go?Read →ReferenceForm backend guideOpen →

Building forms with ChatGPT, Claude, Cursor, or v0? Connect the native MCP server and give your agent a production form backend.

Explore the MCP server →

Give your form a production backend.

One endpoint adds delivery, spam filtering, storage, and integrations. Start with 500 free submissions — no card, no time limit.

Create free accountRead the docs →
Secure checkoutSSL encryptionPrivacyProtected
VISAAMERICANEXPRESSstripe