Using the Entity Autocomplete Element for Referencesfor Drupal 11 , 10 , 9 , and 8

Last updated :  

Sometimes a form field shouldn't collect a plain value at all — it should reference something that already exists in Drupal: a user, a taxonomy term, a piece of content. entity_autocomplete is the built-in element for exactly that: type a few characters, get a live-searched dropdown of matching entities, and end up with a real reference instead of a typed-out guess at a title.

What you'll learn in this lesson

  • The entity_autocomplete definition and its required #target_type
  • Narrowing suggestions with #selection_settings
  • What the submitted value actually looks like — and why it's not just an ID

A basic entity autocomplete

$form['author'] = [
  '#type' => 'entity_autocomplete',
  '#title' => $this->t('Author'),
  '#target_type' => 'user',
];

#target_type is required — it's the entity type ID (node, user, taxonomy_term, or any custom entity type) that the autocomplete searches against and validates against.

Narrowing the search with #selection_settings

$form['tags'] = [
  '#type' => 'entity_autocomplete',
  '#title' => $this->t('Tags'),
  '#target_type' => 'taxonomy_term',
  '#selection_settings' => [
    'target_bundles' => ['tags'],
  ],
  '#tags' => TRUE,
];

#selection_settings['target_bundles'] restricts suggestions to specific bundles — here, only terms from the "tags" vocabulary, not every taxonomy term on the site. #tags => TRUE switches the field to accept a comma-separated list of multiple references in one text input, the same interaction pattern as a node's own tags field.

What the submitted value actually contains

This is worth understanding precisely: the field displays as "Some Title (42)" — the entity's label followed by its ID in parentheses — but internally, on submission, Drupal parses that string back into just the numeric target ID for you.

$author_uid = $form_state->getValue('author');
// $author_uid is an integer, e.g. 42 — already parsed from "Jane Smith (42)".

With #tags => TRUE, the value comes back as an array of target IDs instead of a single integer.

The "(id)" suffix isn't decorative — it's how validation actually works. If a user manually types a label that doesn't exactly match any real entity (no valid (id) attached), form validation rejects it automatically. This is what makes entity_autocomplete a genuine reference field rather than just a fancy-looking text box — it can't submit a reference to something that doesn't exist.

Quick check: you set #target_type => 'node' with no #selection_settings at all. What happens when a user types? (They get autocomplete suggestions from every node on the site, regardless of content type — always add target_bundles in #selection_settings if you actually want to restrict suggestions to specific content types.)

Key takeaways

  • #target_type is required and determines which entity type the field searches and validates against.
  • Use #selection_settings['target_bundles'] to restrict suggestions to specific bundles rather than the entire entity type.
  • The submitted value is already parsed to the numeric target ID (or an array of IDs with #tags => TRUE) — not the raw "Label (id)" display string.

Coming up next

You've now covered every visible element type in common use. Next, a genuinely invisible one — the hidden field, for carrying data through a form without displaying it at all.