splitforms.com

Contact form · jQuery

jQuery AJAX contact form, no backend code

If your site already loads jQuery, you're three method options away from a working contact form. Serialize the form with FormData, POST via $.ajax, and read the JSON response in .done()/.fail(). No new dependencies, no server route, no fetch polyfill for legacy browsers.

  • 500 free / mo
  • 14ms latency
  • No backend code
jQuery contact form — copy-paste code for splitforms

No backend code

No server, API route, or SDK. Your jQuery form posts straight to one endpoint.

Straight to your inbox

Every submission is emailed to you and saved to a searchable dashboard — spam filtered before it reaches you.

Design without limits

It's your own jQuery markup and styles. Splitforms is only the backend, so nothing constrains how the form looks.

Copy-paste ready

Your jQuery contact form, ready to paste.

Replace YOUR_ACCESS_KEY with the key from your dashboard — that's the whole integration. No SDK to install, no build step, just the html you already write.

Generate access key
contact.html
<!-- Include jQuery once per page (skip if your site already loads it) -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

<form id="contact" autocomplete="off">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />

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

  <!-- Honeypot — invisible to humans -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" />

  <button type="submit">Send</button>
  <p id="status"></p>
</form>

<script>
  $(function () {
    $("#contact").on("submit", function (e) {
      e.preventDefault();

      var $form   = $(this);
      var $status = $("#status");
      var $btn    = $form.find('button[type="submit"]');

      $btn.prop("disabled", true).text("Sending…");
      $status.text("");

      $.ajax({
        url: "https://splitforms.com/api/submit",
        method: "POST",
        // Hand jQuery a real FormData so file fields (and multipart) work:
        data: new FormData(this),
        processData: false,   // do NOT turn FormData into a url-encoded string
        contentType: false,   // let the browser set multipart/form-data; boundary=…
        dataType: "json",
      })
        .done(function (data) {
          if (data.success) {
            $status.text("Thanks — we'll be in touch.");
            $form[0].reset();
          } else {
            $status.text(data.message || "Something went wrong.");
          }
        })
        .fail(function () {
          $status.text("Network error — please try again.");
        })
        .always(function () {
          $btn.prop("disabled", false).text("Send");
        });
    });
  });
</script>

How to add it

How to add a contact form to a jQuery website.

To add a contact form to a jQuery website you need three things: a free splitforms access key, the html snippet above, and your key pasted into it. No backend, server, or SDK — the form posts to one URL and every submission lands in your inbox and dashboard.

Get your free splitforms access key

Sign up at splitforms.com, verify your email, and copy your access key from the dashboard. No credit card required.

Drop the jQuery snippet into your project

Copy the jQuery code example into your project and replace YOUR_ACCESS_KEY with the key from step 1.

Receive submissions in your dashboard

Submissions arrive in the splitforms dashboard within seconds. Free includes inbox delivery; Pro adds Slack, Discord, Sheets, or any signed webhook URL.

Where submissions go

Where do your jQuery form submissions go?

Every submission is emailed to you and saved to a searchable dashboard — spam filtered before it ever reaches you. Search, export to CSV, or forward it to a webhook or Slack on Pro.

  • 500 submissions per month, free forever
  • Honeypot + AI spam classifier on every plan
  • Signed webhooks to Slack, Discord, your server
jQuery contact form submissions in the splitforms dashboard

No backend needed

Do you need a backend for a jQuery form? No.

Your jQuery form posts standard FormData to one URL. Splitforms validates the access key, runs the spam classifier, and forwards it to your email — so there's no server, API route, or database for you to build or maintain.

  • Works with jQuery 3.x — and equally well on legacy 1.x / 2.x sites
  • Familiar $.ajax / .done / .fail / .always promise chain — no fetch polyfill for old browsers
  • Pairs cleanly with the jQuery Validation plugin for client-side checks
How splitforms processes a jQuery form submission

Best practices

What a production-ready jQuery form needs.

The difference between a form that works in the demo and one that survives launch traffic — the production-tested defaults, in priority order.

  • Pass new FormData(this) as the data option, not $(this).serialize(). FormData handles file uploads and produces the multipart body splitforms expects; serialize() strips files and only emits url-encoded key/values.
  • Read data.success inside .done() for the real outcome; reserve .fail() for network/parse failures. They are different failure modes and conflating them hides splitforms' 4xx error messages.
  • Disable the submit button with $btn.prop('disabled', true) at the start and re-enable it inside .always() so it resets whether the call succeeded or failed.
Production-ready jQuery contact form best practices

How SplitForms works

From form to workflow in 3 simple steps.

Connect your form, collect every submission, and send data where it needs to go — without building backend infrastructure.

A SplitForms contact form submission launching straight to your inbox

Add your endpoint

Point your form to your unique SplitForms endpoint. That's it.

HTML form pointing at a SplitForms submit endpoint

Receive submissions

We instantly capture and organize every submission in your inbox.

Submissions inbox with searchable leads and status pills

Route anywhere

Send data to email, spreadsheets, CRMs, webhooks, and 7,000+ apps.

Generic integration tiles for email, sheets, chat, CRM, automate, and webhook

No credit card required. Set up in under 60 seconds.

Connect & automate

Connect your favorite tools and automate everything

SplitForms works with the destinations you route to and the platforms you build on — from Slack and Sheets to WordPress, Shopify, and Next.js.

Connect your SplitForms form to Slack, Google Sheets, Mailchimp, Zapier and more

Trusted by indie teams and agencies shipping forms worldwide

PETAL/COKRAFT.DELINEAR-XBUILD.DEVSTUDIO 71MERIDIANFRAME&CO

Testimonials

Loved by developers shipping at every scale.

40 quotes on record — from indie hacks to agency migrations.

Questions

jQuery contact form questions.

View all FAQs
How do I submit a form with jQuery $.ajax to splitforms?

Build a FormData from the form (new FormData(this)), pass it to $.ajax with processData: false and contentType: false, and POST to https://splitforms.com/api/submit. The access_key hidden input carries your key; in .done(), read data.success to know whether the submission was accepted.

Can I use $.post instead of $.ajax?

Yes, but only in the full-call form. $.post(url, formData) still defaults processData and contentType to true, which mangles FormData. Use $.ajax({ url, method: 'POST', data: formData, processData: false, contentType: false, dataType: 'json' }) — the shorthand can't override those options.

Do I still need jQuery in 2026? Isn't fetch enough?

For greenfield projects, yes — native fetch + FormData does everything splitforms needs (see the AJAX page). jQuery earns its keep when the site already loads it: legacy codebases, Bootstrap 4 themes, older WordPress frontends. Don't add jQuery just for this form.

How do I handle errors with jQuery?

Two layers. .fail() catches transport and parse errors (network down, non-JSON response, 5xx). .done() runs on 2xx — always inspect data.success; if false, render data.message for the user. Re-enable the button inside .always() so it resets on both paths.

How do I add the jQuery Validation plugin?

Load jquery.validate.js after jQuery, call $('#contact').validate({ rules: { … } }), and at the top of your submit handler check if (!$(this).valid()) return; before building FormData. Keep the honeypot botcheck field out of the rules object so the validator ignores it.

Does it work with older jQuery (1.x / 2.x)?

Yes. FormData, processData: false, and contentType: false are supported back to jQuery 1.5, when $.ajax was rewritten around jqXHR. The .done/.fail/.always promise chain also dates to 1.5. If you're stuck on jQuery 1.4 or earlier, the jqXHR promise API doesn't exist — upgrade first.

processData: false + contentType: false are mandatory with FormData

jQuery's $.ajax defaults serialize the data option into a URL-encoded string and set Content-Type: application/x-www-form-urlencoded itself. If you pass a FormData object without overriding those defaults, jQuery calls .toString() on it (yielding [object FormData]), drops every field, and splitforms sees an empty body — returning a 400 with missing access_key. Always pass processData: false (don't serialize) and contentType: false (don't auto-set the header; the browser generates the correct multipart/form-data; boundary=…). It is the single most common reason a jQuery splitforms form silently fails.

.done() fires on every 2xx — you must inspect data.success, not just the promise

jQuery resolves or rejects based on HTTP status AND whether the body parsed as the requested dataType. With dataType: 'json', a 200 with malformed JSON rejects (.fail()), and a 4xx/5xx rejects too. But a 200 with { success: false } resolves into .done() — that's exactly how splitforms signals an invalid key, spam flag, or rate-limit. Treat .done as 'transport ok' and branch on data.success for the real outcome. .fail is for network and parse failures only.

Re-running $(function(){}) on SPA / Turbolinks / pjax route changes stacks submit handlers

If your site swaps page content without a full reload (Turbolinks, Hotwire Drive, pjax, or any SPA-ish router) and your init code runs again on each navigation, $('#contact').on('submit', …) binds a NEW handler every time — the next submit fires duplicate POSTs to splitforms. Either bind once with event delegation on a stable parent ($(document).on('submit', '#contact', …)) or unbind first ($('#contact').off('submit').on('submit', …)). The jQuery Validation plugin's .validate() has the same stacking bug if called repeatedly.

Simple pricing

Start free. Scale when you need more.

Choose a plan that fits your workflow — from a free form endpoint to full automations, exports, and higher submission limits.

Free

$0

Free forever

 
Best for testing

For side projects and indie devs.

  • 500 submissions / mo
  • Unlimited forms
  • Email notifications included
  • Honeypot spam filtering
  • Submissions dashboard
  • MCP setup stays free
  • No credit card required

3-Year

$59/ 36 months
was $99 · save 40% · new-user price

Pay $59. 3 years sorted.

  • 15,000 submissions / mo
  • Unlimited forms
  • Everything in Pro
  • Renews every 3 years
  • Long-term discount
  • Priority support included
  • Vote on the roadmap

No credit card required on Free • Cancel anytime