There seem to be many people trying to pass HTML markup into a twig template and having trouble doing it. It sounds like the best solution is to use something like:

$variables['test'] = ['#markup' => '<strong>some markup</strong>'];

But, when would this be preferable (or necessary) over adding the markup in the twig template instead?

2 Answers 2


It's not possible to put all html markup in templates. Often for example in case of an error you need to generate some extra markup.

If it is a string constant like in your example this is no problem.

If you have variables, don't concatenate in markup.

Use Drupal\Component\Render\FormattableMarkup instead:

$variables['error']['#markup'] = new FormattableMarkup('<strong>Error @message at line @line</strong>', [
  '@message' => $message,
  '@line' => $line,

Most times you need to make this translatable and this is why t() is still one of the most used functions in drupal:

$variables['error']['#markup'] = t('<strong>Error @message at line @line</strong>', [
  '@message' => $message,
  '@line' => $line,

If you are in a class use $this->t().

To summarize, the answer to the question is yes, there is justification for adding html in php. This is, if you need to react dynamically on things happening in your code. Then instantiate a new FormattableMarkup object. If you need translation, you can simply use t().


The other answer is the most likely/frequent scenario, the only other scenarios I am able to think of are:

1) It's a preference thing, the person does not want to add more markup to template.html.twig so it looks cleaner.

2) '<strong>some markup</strong>' is actually a variable which you cannot predict the markup of.

$variables['test'] = ['#markup' => $foo];

Maybe $foo has a value from a WYSIWYG enabled field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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