HTML form hidden field

A hidden input is a normal form field with no visible box. It travels with the submission like any other value, which is exactly why it must never carry anything private.

An HTML form hidden field is an <input type="hidden">: a named value that is submitted with the form but never drawn on the page.

<input type="hidden" name="source" value="pricing-page">

It has no box, no label, and no place in the tab order. The browser sends it exactly as it sends a text box.

The developer tools element panel showing a hidden input and its value inside a rendered form.
The developer tools element panel showing a hidden input and its value inside a rendered form.

That last sentence is the whole subject. A hidden field is hidden from the reader's eyes and from nothing else.

What it is actually used for

The recurring pattern is context: something the page knows and the reader does not need to type.

Use Example value Why it is hidden
Source tracking pricing-page The reader has no reason to fill it in
Record identifier order_4812 Tells the handler which row to update
Form routing support One endpoint, several forms
CSRF token server-generated string Must be present, must not be typed
Step state step=2 Carries progress through a multi-page form
Honeypot empty on purpose Filled in only by bots

The identifier row is the common one. An edit form loads a record, shows the editable parts, and carries the record id along in a hidden input so the handler knows what it is saving.

Why it is not a security feature

The value lives in the HTML the browser downloaded. Anyone can read it, change it, and submit the changed version.

<!-- Do not do this -->
<input type="hidden" name="price" value="19.00">
<input type="hidden" name="role" value="user">

Both of those are editable in the developer tools in about four seconds. A price sent from the browser is a suggestion, not a fact.

The rule is short. Anything the reader must not control has to be decided on the server, from the session, after the submission arrives.

A CSRF token is the apparent exception and is not one. Its safety comes from being unguessable and checked server-side, not from being invisible.

Hidden field versus a field hidden with CSS

These look similar and behave differently, and the difference produces a specific bug.

  • type="hidden" is excluded from constraint validation. Marking it required does nothing.
  • A text input with display:none is still a real form control. If it is required and empty, the browser blocks submission and tries to focus a field nobody can see.

The symptom is a submit button that appears dead with no message. If that is happening, look for a required control inside a collapsed section before you look anywhere else.

Use type="hidden" when the field is structural. Use CSS only when the field is genuinely meant to become visible later.

Reading hidden fields back

They arrive with everything else. FormData collects them without being told:

const data = new FormData(document.querySelector('form'));
console.log(Object.fromEntries(data));
// { source: 'pricing-page', name: 'Hana', email: 'hana@example.com' }

Setting one from a script is the same as any other input:

document.querySelector('input[name="source"]').value = location.pathname;

That pattern lets a single form template record which page it was embedded on, which is worth having before you start routing submissions into a spreadsheet.

The collected submission object in the console, with the hidden source value alongside the typed fields.
The collected submission object in the console, with the hidden source value alongside the typed fields.

The honeypot variation

A field that is supposed to stay empty is a cheap filter against automated submissions. Bots fill in everything they find.

<div aria-hidden="true" style="position:absolute;left:-9999px">
  <label>Leave this empty
    <input type="text" name="website" tabindex="-1" autocomplete="off">
  </label>
</div>

This one is deliberately not type="hidden", because some bots skip hidden inputs. It is pushed off-screen instead and kept out of the tab order.

aria-hidden keeps it away from screen readers, and turning off autocomplete stops a browser helpfully filling it in, for the same reason as in other fields that should not be completed automatically.

On the receiving end, discard any submission where website has a value.

The alternatives worth considering first

A hidden field is not the only way to carry context, and sometimes it is the wrong one.

The URL. A value in the query string does the same job and is visible, shareable and bookmarkable. Good for a campaign source, bad for anything you would rather not see in a server log.

The session. Anything the server already knows about the signed-in person should come from the session on arrival, never from a field the browser sends.

A data attribute. If the value is only used by your own script and never submitted, data- on the form element keeps it out of the payload entirely.

Separate endpoints. Instead of a hidden form_type field, post to two different URLs. The routing is then a fact of the request rather than a claim inside it.

Reach for a hidden input when the value genuinely has to make the round trip and the reader has no business typing it.

A checklist before the form goes out.

  • Every hidden field has a name. Without one it is never submitted.
  • No price, role, permission or user id that the server could work out itself.
  • The value is validated on arrival, with the same suspicion as a text box.
  • Tokens are generated per session, not hard-coded into the file.
  • The names mean something in your data. hidden1 will be a problem in three months.

Sending the form to the people who fill it in

A finished form page is usually the point at which the practical problem starts. An .html file with a form and a script in it is the shape mail gateways are trained to strip, so the attachment quietly never arrives.

The same form pasted into a NOS document, rendering as a page with its own address.
The same form pasted into a NOS document, rendering as a page with its own address.

Paste the HTML into a NOS document instead. It renders as written, hidden fields intact, at an address you can send in one line. Share, then Share link, then Create link.

Because the address does not change when the content does, you can add a field or fix a label later and the link already points at the new version. Turning a form into a link covers that route end to end.

Questions people ask

What is a hidden field in an HTML form?

An input with type="hidden". It is not drawn on the page and cannot be focused or edited by the reader, but it has a name and a value and is submitted with the rest of the form. It is the standard way to attach context the person filling the form does not need to see.

Is a hidden field secure?

No. The value sits in the page source, visible to anyone who opens view-source or the developer tools, and it can be changed there before submitting. Treat every hidden value as reader-supplied and validate it on the server exactly as you would a text box.

What is the difference between type="hidden" and display:none?

A hidden input is never rendered and is not expected to be. A visible input hidden with CSS still takes part in validation, so a required field hidden that way can block submission with an error nobody can see. Use type="hidden" when the field is structural.

Do hidden fields need a label?

No. They are not focusable and screen readers skip them, so a label has nothing to point at. Give the field a clear name attribute instead, since that name is what appears in your data.

Keep reading