I added a login form to a node with following code :

function my_theme_preprocess_node(&$variables) {
  $node = $variables['node'];
  $variables['login_form'] = FALSE;
  $variables['username'] = FALSE;
  if(Drupal::currentUser()->isAnonymous()) {
    $form = Drupal::formBuilder()->getForm(\Drupal\user\Form\UserLoginForm::class);
    $variables['login_form'] = Drupal::service('renderer')->renderPlain($form); // renderRoot
  } else {
    $variables['username'] = Drupal::currentUser()->getDisplayName();

If I change the line

$variables['login_form'] = Drupal::service('renderer')->renderPlain($form);


$variables['login_form'] = Drupal::service('renderer')->renderRoot($form);

I can't see any difference. Both seem to work either.

I read the docs, the latter mostly checks

Whether we're currently in a ::renderRoot() call.

but it is not very explicit about why /when this check is useful and so when to use the former or latter function ?

1 Answer 1


renderRoot() is for rendering the final result returned by a controller. renderPlain() is for rendering HTML which is not part of a page and is used for other purposes like emails. In your case the correct method would be render(), because this is the only render method which can bubble up metadata to the page. But you don't need to render at all, because you can put the unrendered form build array in a template variable and it will be rendered automatically when printed in TWIG.


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.