Set the page title to H1 only on the homepage with Twig and Drupal 8

I’m building a Drupal 8 theme and wanted to set it up so…

  • If you’re on the homepage, the site title at the top of the page is the h1
  • If you’re not on the homepage, the site title is just a div allowing the page title to be the only h1

Best practices for digital accessibility and SEO ask us to make sure there is only one H1 on the page (well, it’s a touch more complicated with article but yea).

Drupal 8 uses Twig, an easier way to write PHP. It just takes two relatively simple steps to get this done.

  1. Allow is_front to be used in templates other than page.template.html. is_front asks the template to check if we’re on the front page.
  2. Create a lil conditional statement to decide if the html tag should be h1 or div

Make is_front available in other templates

Add this block in your mytheme.theme file. Replace mytheme with the name of your theme.

/* Allow is_front to be used on other templates */
function mytheme_preprocess(&$variables, $hook) {
try {
$variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage();
}
catch (Exception $e) {
$variables['is_front'] = FALSE;
}
// Ensure the cache varies correctly (new in Drupal 8.3).
$variables['#cache']['contexts'][] = 'url.path.is_front';
}

I didn’t come up with this — I got help in the drupaltwig.slack channel. Thanks!

Use is_front in a template to choose between an h1 and div

I have a Drupal 8 block called ‘branding’ where set up how my logo and site name appear. The template file is block — mytheme-branding.html.twig

For me, the only thing I needed to change was the HTML tag. So,

<h1 class="page-title">{{ site_name }}</h1>

Or

<div class="page-title">{{ site_name }}</div>
  • site_name is a Drupal 8 built-in variable, so be yourself and have fun!
  • page-title is just an example of a class. I use it to style this element the same regardless of if it is semantically an h1 or a div.

Since the only difference is the tag, I figure I’ll just change that out.

I use Twig’s set to create a variable based on a condition in block — mytheme-branding.html.twig

Twig variables:
More about Twig variables: https://twig.symfony.com/doc/2.x/tags/set.html
{% set sitename_tag = is_front ? 'h1' : 'div' %}

“Create a variable called sitename_tag. IF this is the front page THEN the value is h1 ELSE it is div.”

Then, use the variable.

<{{ sitename_tag }} class="page-title">{{ site_name }}</{{ sitename_tag }}>

I can imagine this is a fairly common desire. I thought I’d share how I got it done.