In order to send html email using drupal/swiftmailer I load and view a node.

Then I pass it to the rendere. In the email sent, generated node__links are empty. As node_links uses #LazyBuilder, Im then not sure to use the correct way.


function mymodule_mail($key, &$message, $params) {
   switch ($key) {
       case 'mail_node':
           $message['from'] = \Drupal::config('system.site')->get('mail');
           $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
           $message['subject'] = t('Mail subject');

           $node = Node::load($params['nid']);
           $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');

           $body_data = [
               '#theme' => 'mymodule_mail_node',
               '#content' => $view_builder->view( $node ),

           $message['body'][] = \Drupal::service('renderer')->render($body_data);


 {# simply render the whole body #}
 {{ body }}

output results in mail

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'links__node' -->
    x links--node.html.twig
    * links.html.twig
<!-- BEGIN OUTPUT from 'core/themes/classy/templates/content/links--node.html.twig' -->

<!-- END OUTPUT from 'core/themes/classy/templates/content/links--node.html.twig' -->

When I render the same content into an html page, node__links are correctly filled.

Any recommandation would be appreciate. Thanks

1 Answer 1


Use renderPlain():

$message['body'][] = \Drupal::service('renderer')->renderPlain($body_data);

From the documentation:

Renders final HTML in situations where no assets are needed.

Calls ::render() in such a way that placeholders are replaced.

Useful for instance when rendering the values of tokens or emails, which need a render array being turned into a string, but do not need any of the bubbleable metadata (the attached assets and cache tags).

Source: Renderer::renderPlain

"When I render the same content into an html page, node__links are correctly filled."

render() in a page works, because the page has a render context for the metadata to bubble up, so that the placeholders can be replaced later.


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.