Skip to content

The Webflow rulebook

Form rules

Webflow can collect form submissions for you and email them to you — but only if it recognises the form as a form. These rules give it the exact shape it looks for.

The idea in one paragraph

When a form is imported, Webflow looks for particular wrappers and attributes. When it finds them, the form becomes a real Webflow Form block: submissions appear in your Webflow dashboard, spam protection works, and a thank-you message shows after sending. When it does not, the form arrives as ordinary boxes that look right but send nowhere.

These rules are not checked automatically — a computer cannot always tell a form's intent — but the AI follows them, and they are what decides whether the form works after export.

The rules

The form tag carries a name, an id, a method and data-ht-form

Not auto-checked
html
<form name="contact-form" id="contact-form" method="post" class="contact-form" data-ht-form>
Why

The name is what the form is called in your Webflow submissions list, so you can tell your contact form from your newsletter form. method="post" sends the answers privately rather than in the page address, and data-ht-form is how HTFlow's own scripts find it.

Think of it like

The name on a mailbox. Without it, letters for two different people land in one pile.

Every field has a name, an id and a label

Not auto-checked

Each input has a name and an id, and a <label> whose for matches that id.

Why

The name becomes the column heading in your list of submissions — without it, the answer arrives with no idea what question it belongs to.

The label, linked by for and id, tells screen readers what the field is for, and lets visitors click the label text to jump into the field. This is the one place ids are used: to connect a label to its field, never for styling.

Think of it like

Column headings on a spreadsheet. A row of answers with no headings is just a row of words.

html
<label class="contact-form__label" for="email">Email</label>
<input class="contact-form__input" type="email" id="email" name="email" required>

Checkboxes and radio buttons sit in their own wrapper

Not auto-checked

Each checkbox is wrapped in <div data-wf-checkbox>, and each radio button in <div data-wf-radio>, with its label inside the same wrapper.

Why

Webflow has its own Checkbox and Radio elements, and it recognises them by this wrapper. Without it, the box still appears, but as plain markup a designer cannot restyle from Webflow's form settings.

Think of it like

Putting each item in the box with its own label, instead of loose in the van.

Rejected

<input type="checkbox" id="news" name="news">
<label for="news">Keep me posted</label>

Correct

<div data-wf-checkbox>
  <input type="checkbox" id="news" name="news">
  <label for="news">Keep me posted</label>
</div>

A dropdown starts with an empty choice

Not auto-checked
html
<select id="topic" name="topic">
  <option value="">Select...</option>
  <option value="sales">Sales</option>
</select>
Why

The empty first option means nobody submits “Sales” just because it happened to be first. If the field is required, the visitor has to make a real choice.

Think of it like

A form that leaves the box blank rather than ticking “Yes” for you.

The submit button says what is happening

Not auto-checked
html
<button class="contact-form__submit" type="submit" data-wait="Please wait...">Send</button>
Why

data-wait is the text Webflow shows on the button while the form is sending. Without it the button looks frozen, and people click it again — sending the form twice.

Think of it like

A shop assistant saying “one moment” instead of staring silently.

Success and error messages sit next to the form, not inside it

Not auto-checked

The thank-you message is a <div data-wf-success> and the failure message a <div data-wf-error>. Both come straight after the closing </form> tag — beside the form, not inside it.

Why

When someone sends the form, Webflow hides the form and shows the success message in its place. If the message were inside the form, it would be hidden along with it, and the visitor would see nothing at all.

Think of it like

A receipt handed to you after you post your envelope. It cannot be inside the envelope — that is gone.

Attributes are separated by spaces

Not auto-checked

Every attribute in a tag has a space before it: <input type="text" id="name" name="name">.

Why

Browsers are forgiving about a missing space, but the export to Webflow is not — two attributes run together are read as one broken attribute, and the field loses its name or type.

Think of it like

Words in a sentence. “Typetext” is not two words to a machine.

A complete form

html
<form name="contact-form" id="contact-form" method="post" class="contact-form" data-ht-form>
  <label class="contact-form__label" for="name">Name</label>
  <input class="contact-form__input" type="text" id="name" name="name" required>

  <label class="contact-form__label" for="email">Email</label>
  <input class="contact-form__input" type="email" id="email" name="email" required>

  <div data-wf-checkbox>
    <input type="checkbox" id="subscribe" name="subscribe">
    <label class="contact-form__check" for="subscribe">Keep me posted</label>
  </div>

  <button class="contact-form__submit" type="submit" data-wait="Please wait...">Send</button>
</form>

<div data-wf-success>Thanks — we will reply within 24 hours.</div>
<div data-wf-error>Something went wrong. Please try again.</div>