How to render HTML into a variable programmatically Let's assume you have a "product" node $node, and for some reason you want to render HTML from $node into a variable $html using a Twig template. I'm a bit desperate yet, what would you do?

Additional info 1: We are not in a controller, but in a simple class that is registered as a service.

Additional info 2: 4k4 's answer does work if I call my class from a controller. But as soon I call it from a Drupal Console command I get an Exception "The theme implementations may not be rendered until all modules are loaded."

Edit: The complete solution

Obviously not all modules are loaded if we call the service inside a Drupal Console command. The Theme Manager will honor this with the aforementioned exception, so we have to force load the modules:

\Drupal::moduleHandler()-&gt;loadAll(); // Load all modules if not loaded already


Now it's safe to call the renderPlain() method as suggested below:

$view_builder = \Drupal::entityTypeManager()-&gt;getViewBuilder('node');
$build = $view_builder-&gt;view($node, $view_mode, $langcode);
$html = \Drupal::service('renderer')-&gt;renderPlain($build);


Edit: But what about a full page?

If you intend to render not only the node content but a full page (from &lt;html&gt; to &lt;/html&gt;) you have to have the kernel handle an appropriate sub-request .
To render a plain node view, for example for emails, use this code:

$view_builder = \Drupal::entityTypeManager()-&gt;getViewBuilder('node');
$build = $view_builder-&gt;view($node, $view_mode, $langcode);
$html = \Drupal::service('renderer')-&gt;renderPlain($build);


If you want to customize the output, use a special view mode and a template node--[view-mode].html.twig.

Edit: Full page

You can build more complex render arrays:

  $view_builder = \Drupal::entityTypeManager()-&gt;getViewBuilder('node');
  $content = $view_builder-&gt;view($node, $view_mode, $langcode);
  $build = [
    '#type' =&gt; 'html',
    'page' =&gt; [
      '#type' =&gt; 'page',
      '#theme' =&gt; 'page',
      '#title' =&gt; 'Title',
      'content' =&gt; $content,
    ],
  ];

  $html = \Drupal::service('renderer')-&gt;renderPlain($build);


This is only a basic version of a page, if you want the full version with all features like attachments and libraries you need a request on Drupal.