Using the Hidden Element to Carry Non-Visible Datafor Drupal 11 , 10 , 9 , and 8

Last updated :  

Not every value a form needs to carry through a submission belongs in front of the user. A hidden field lets you pass data along with the form — an ID, a token, a computed value from an earlier step — without rendering any visible input at all.

What you'll learn in this lesson

  • The basic hidden field definition
  • Why hidden fields are for carrying data, not for protecting it
  • A real use case: passing an entity ID through a multi-step form

A basic hidden field

$form['entity_id'] = [
  '#type' => 'hidden',
  '#value' => $node->id(),
];

Notice this uses #value, not #default_value — a hidden field has no visible UI a user could ever edit, so there's no distinction between "initial value" and "current value" the way there is for a visible text field. #value forces the value directly, and it's what gets submitted, full stop.

A real use case: multi-step state

$form['step'] = [
  '#type' => 'hidden',
  '#value' => $form_state->get('current_step') ?? 1,
];

This is a common pattern in hand-rolled multi-step forms (before you'd typically reach for $form_state->set()/get() directly, which is usually the better tool) — carrying a piece of state across submissions by round-tripping it through the form itself as a hidden value.

Hidden does not mean secure. Anyone can view a page's source, open browser devtools, or intercept the raw HTTP request and see — or modify — a hidden field's value before it's submitted. Never rely on a hidden field to protect something a malicious user shouldn't be able to change (a price, a permission level, another user's ID). Anything genuinely sensitive belongs in server-side session/form-state data, or must be re-validated against the database in your submit handler regardless of what the hidden field claims.

Quick check: you store a product's price in a hidden field so the submit handler can charge the right amount. Is this safe? (No — a user can edit the hidden field's value in their browser before submitting, changing the price to anything they want. Always re-look up the real price server-side from the product's actual stored data, never trust a client-submitted value for anything with real consequences.)

Key takeaways

  • Hidden fields use #value, not #default_value — there's no visible state to distinguish between.
  • A hidden field is invisible in the rendered UI, but its value is fully visible and editable in the raw HTML/request — never rely on it for security.
  • For anything sensitive or consequential, re-validate against real server-side data in your submit handler, regardless of what a hidden field claims.

Coming up next

Next up: a genuinely tricky element type to get right — date and datetime fields, and the timezone/format gotchas that come with them.