splitforms.com
guide · form types

Registration Form in HTML — Working Code for 2026

A registration form with name, email, password, and confirm-password fields — semantic HTML, native validation, accessibility-first labels. POSTs to splitforms (free 1,000/mo). The form code, the validation rules, and the backend integration on one page.

html
<form action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input type="hidden" name="_subject"   value="New registration" />
  <input type="hidden" name="redirect"   value="https://yoursite.com/welcome" />

  <label>
    Full name
    <input name="name" type="text" required minlength="2" autocomplete="name" />
  </label>

  <label>
    Email
    <input name="email" type="email" required autocomplete="email" />
  </label>

  <label>
    Password
    <input name="password" type="password" required minlength="8"
           autocomplete="new-password" />
  </label>

  <label>
    Confirm password
    <input name="password_confirm" type="password" required minlength="8"
           autocomplete="new-password" />
  </label>

  <label>
    <input type="checkbox" name="agree_terms" required />
    I agree to the <a href="/terms">terms of service</a>
  </label>

  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" />
  <button type="submit">Create account</button>
</form>

A registration form is a contact form with stricter validation rules. Same `<form>` wrapper, same submit mechanics, but every field has more requirements: passwords must be a minimum length, emails must be unique, terms must be accepted. Most of the validation work happens server-side (on your backend) — the HTML's job is to fail loudly on obvious mistakes before the user even submits.

The form above uses every native validation primitive: `required` for mandatory fields, `type="email"` for email format checking, `minlength="8"` for password length, the terms checkbox uses `required` so the user can't submit without agreeing. Modern browsers show inline error messages automatically — no JavaScript needed for the baseline.

Password confirmation is the one case where native HTML falls short. There's no `equalTo` attribute, so you need ~5 lines of JavaScript to compare the two password fields and show an error if they don't match. The snippet for that is in the alternative-code section below.

The form POSTs to splitforms's `/api/submit` endpoint. splitforms emails you the registration, stores it permanently, and fires webhooks. If you're building a real registration system (where users actually log in), you'll want a database-backed signup flow — use splitforms for the lead-capture form, then write users to your auth provider via a webhook handler.

Password-match validation (5 lines of vanilla JS)

javascript
const form = document.querySelector("form");
const password = form.querySelector("[name=password]");
const confirm = form.querySelector("[name=password_confirm]");

confirm.addEventListener("input", () => {
  confirm.setCustomValidity(
    confirm.value === password.value ? "" : "Passwords don't match"
  );
});

How to set this up

Step 01

Use semantic input types

type=email for email, type=password for passwords, autocomplete=name/email/new-password for browser autofill support.

Step 02

Add native validation

required, minlength, type=email — the browser blocks malformed submissions before they hit the network.

Step 03

Handle password confirmation in JS

Native HTML has no equalTo. 5 lines of JS using setCustomValidity does the job — no library needed.

Step 04

POST to splitforms

Submissions land in your inbox and dashboard. Webhook into your auth provider if you're building a full account system.

Native validation, password-match in 5 lines of JS, splitforms backend.

Frequently asked questions

How do I make a registration form in HTML?

Use a <form action method=POST> with inputs for name, email, password, password confirmation, and a terms-of-service checkbox. Use type="email" and type="password" for native validation, required for mandatory fields, minlength="8" for password length. POST to a backend service like splitforms (free 1,000/mo) or your own /api/register endpoint.

Should I use type="password" or a custom show/hide toggle?

type="password" is the baseline — required for password manager compatibility, accessibility, and browser autofill. Add a show/hide button via JS if you want, but keep the input as type="password" by default.

How do I validate that the two passwords match?

Use setCustomValidity in JS. On every input event on the confirm field, set it to '' if values match, or 'Passwords don\'t match' if they don't. The native validation UI then displays the error like any other required-field error.

Is splitforms the right backend for a real registration system?

splitforms is the right backend for capturing the registration (email goes to you, submission stored, webhook fires). For full account creation (writing the user to your auth database, sending a confirmation email link, etc.), wire a webhook from splitforms to your auth provider — Supabase, Clerk, Auth0, etc.

Do I need a CAPTCHA?

Probably not. The honeypot field + splitforms's AI spam classifier catches most bot submissions. Add CAPTCHA only if you're seeing real human-driven abuse — which is rare for a registration form.

Related guides

Form types

Signup Form in HTML — Working Code with Validation

HTML forms

HTML Form — How to Build and Submit Forms in HTML

HTML forms

HTML Form Action — What It Does and How to Use It

Ship the form, not the backend.

Free for 1,000 submissions/month. Email delivery, AI spam filtering, signed webhooks, real dashboard — all on the free plan. No credit card.

Get a free access key →