Is there any way to add a region into html.html.twig? I want to have one inside tag to be able to render different js counters through Block Layout

  • Can you provide more details about your issue?
    – Andrew Nim
    Nov 22, 2016 at 9:22
  • I'm trying to create a region that will be rendered in the area outside of the page inside html.html.twig. things like google analytics, facebook pixel etc. So they could be managed in the block layout as just a block content, rather than putting that code inside head area of the html Nov 22, 2016 at 9:56

2 Answers 2


So, the solution is to add a new region into your theme.info.yml (say before_body) Then the code you'd place into theme_name.theme be:

function theme_name_preprocess_html(&$vars) {
   * moves region before_body into before_body var inside basic html
  if (isset($vars['page']['before_body'])) {
    $vars['before_body'] = $vars['page']['before_body'];
function theme_name_preprocess_region(&$vars){
   * Cleans before_body from standard html markup
  if ($vars['region'] === 'before_body') {
    $vars['content'] = theme_name_clean_special_content($vars['content']);
 * Cleans content from basic markup
 * @param $content
 * @return \Drupal\Component\Render\MarkupInterface|string
function theme_name_clean_special_content($content) {
  /** @var \Drupal\Core\Render\Markup $content */
  $content = preg_replace('~<\/?section.*?>|<h\d?.*?>.*<\/h\d?>|<\/?div.*?>~', '', $content);
  $content = preg_replace('/(?=<!-- (THEME DEBUG|BEGIN OUTPUT|THEME HOOK|FILE NAME SUGGESTIONS|END OUTPUT))([\s\S]*?)-->/i', '', $content);
  $content = preg_replace('/((\r\n|\n|\r)$)|(^(\r\n|\n|\r))$/m', '', $content);
  return \Drupal\Core\Render\Markup::create(trim($content));

Just don't forget to add before_body variable into your basic html template.


There is no way to place regions directly in the html.html.twig template as regions that you operate through block layout are part of the page variable and are rendered in body tag.

HtmlRenderer::prepare() receives the main content render and ensures we have a '#type' => 'page' render array (which corresponds to ):

  1. if the main content render array already is '#type' => 'page', then we're done

  2. otherwise, we need to build that '#type' => 'page' render array. The RenderEvents::SELECT_PAGE_DISPLAY_VARIANT event is dispatched, to select a page display variant.

    • By default, SimplePageVariant is used, which doesn't apply any decorations.

    • But, when the Block module is enabled, BlockPageVariant is used, which allows the site builder to place blocks in any of the page regions, and hence "decorate" the main content.

    • Drupal 8 modules can subscribe to this event as well, and use a different page variant, even on a per-route basis. (Panels, Page Manager etc. can be cleanly implemented thanks to this event.)

  3. HtmlRenderer::prepare() now is guaranteed to be working on a '#type' => 'page' render array. hook_page_attachments() and hook_page_attachments_alter() are invoked. (For attaching page-level assets, that aren't bound to a specific page.)

  4. Renderer (formerly drupal_render()) is called on the '#type' => 'html' render array, which uses the html.html.twig template and the return value is a HTML document as a string.

  5. This HTML string is returned as the Response (specifically, a HtmlResponse object, which is a more specialized subclass of Response).

More info on this page: https://www.drupal.org/docs/8/api/render-api/the-drupal-8-render-pipeline

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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