You've used #required => TRUE in nearly every example so far without a dedicated explanation. This lesson makes it explicit: what it actually does, both visually and functionally, and where its automatic validation stops — since #required alone won't catch everything a real field needs validated.
What you'll learn in this lesson
- What #required does automatically: visual indicator plus server-side check
- What counts as "empty" for different element types
- Where #required's job ends and custom validation begins
The two things #required does
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Email address'),
'#required' => TRUE,
];
Two automatic effects: a visual asterisk added to the label (via CSS, themeable), and a genuine server-side check — if the field is empty on submission, Drupal adds a "field is required" error automatically, before your own validateForm() even runs, without you writing that check yourself.
#empty_option is still selected (which connects directly back to the select lesson's warning about required validation silently not working without one). Know your element's own "empty" definition — #required's automatic check relies on it being correct.Where #required's job ends
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Email address'),
'#required' => TRUE, // Catches: field left completely blank.
];
// #type => 'email' ALSO gets automatic format validation (must look
// like an email) — but that's from the element type, not #required.
// #required only ever checks for emptiness, nothing about content shape.
#required answers exactly one question — "was something entered at all?" — and nothing about whether what was entered is actually valid content. A required textfield accepting a phone number still needs its own custom validation (covered in the Form Validation section) to confirm the entered text actually looks like a phone number; #required alone would happily accept "asdf".
Quick check: a required textfield is meant to collect a US ZIP code. A user submits the single character "x". Does #required catch this as invalid? If you said no — #required only checks that something was entered, not that it's a valid ZIP code — you've understood exactly the boundary between #required and custom content validation.
Key takeaways
#required => TRUEadds both a visual asterisk and a genuine server-side emptiness check, automatically.- "Empty" is defined differently per element type — know your specific element's definition, especially for select and checkboxes.
- #required only checks presence, never content validity — a required field can still contain garbage that passes #required but fails a real content check.
Coming up next
Required enforces presence. Next, helping a user understand what to actually enter in the first place, with #description.