It should be very straightforward and yet, I can't identify the reason why this doesn't add a placeholder to a field in a form:

function posts_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == "node_post_form" || $form_id == "node_post_edit_form") {
    $form['field_post_subject']['#attributes']['placeholder'] = t("blah");

This confirms that the key placeholder is being set:

enter image description here

The hook_form_alter() works as expected for other things I need to change, except the placeholder. I looked everywhere and it's always the same solution so I'm wondering what I'm missing?

  • Did you rebuild the cache? Also, check your theme template and any preprocessing functions; you may be removing or ignoring the placeholder down the line. Commented May 28, 2022 at 8:06
  • Thanks @PatrickKenny. Yes I did rebuild it + tried with other themes including Bartik. I also tried with other forms but with no luck so far.
    – jozi
    Commented May 28, 2022 at 8:18
  • What type of field is it? Commented May 28, 2022 at 9:34
  • 1
    It looks like you set the placeholder on a '#type' => 'container' element. You need to go into the widget.
    – leymannx
    Commented May 28, 2022 at 9:58
  • Thanks for your guidance @leymannx - the solution 4uk4 suggested worked
    – jozi
    Commented May 28, 2022 at 22:40

1 Answer 1


You are now setting the placeholder attribute to a container, which should be visible in the source HTML, but doesn't have any effect on the form.

You need to add the placeholder to a form element. You find at least one, for multi-value or multi-property fields multiple, inside the widget key (in your debug output a children of the container).

Text fields have already a configurable option for placeholders. If you need to overwrite it dynamically you have to look for the form element and set a new #placeholder.

This is the form element you are looking for:


$element['value'] = $element + [
  '#type' => 'textfield',
  '#default_value' => $items[$delta]->value ?? NULL,
  '#size' => $this->getSetting('size'),
  '#placeholder' => $this->getSetting('placeholder'),
  '#maxlength' => $this->getFieldSetting('max_length'),
  '#attributes' => ['class' => ['js-text-full', 'text-full']],
  • Thanks so much for your complete response! For future references, $form['field_name']['widget'][0]['value']['#placeholder'] is where the placeholder is set.
    – jozi
    Commented May 28, 2022 at 22:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.