Add meta description and title programmatically

Last updated on
29 July 2024

This documentation needs review. See "Help improve this page" in the sidebar.

The following example code will override the meta title and description for the Basic Page content type with custom values. Substitute mythemename in the function name with the machine name of your theme. The existing fields title and  body are used which you should replace with the values you desire.

Add this code in your theme mythemename.theme file, and clear the caches.

/**
 * Implements hook_preprocess_html() for html templates.
 */
function mythemename_preprocess_html(array &$variables) {
  // Add META tag title + description for Basic Page node fields.
  // This assumes the 'body' field is present and populated.
  // Load the node entity from current route.
  $node = \Drupal::routeMatch()->getParameter('node');
  if ($node) {
    // Check if node type is basic page.
    if ($node->getType() === 'page') {
      $variables['page']['#attached']['html_head'][] = [
        [
          '#tag' => 'meta',
          '#attributes' => [
            'name' => 'title',
            'content' => $node->get('title')->value,
          ],
        ],
        'title',
      ];
      $variables['page']['#attached']['html_head'][] = [
        [
          '#tag' => 'meta',
          '#attributes' => [
            'name' => 'description',
            // Get 160 characters from Body field, strip tags
            'content' => strip_tags(substr($node->get('body')->value, 0, 160)) . '...',
          ],
        ],
        'description',
      ];
    }
  }
}

The Summary field is empty by default, so the first 160 characters from the Body field are extracted, and tags stripped. For better control, fill out and use the summary value instead, where tags are stripped by default.

To use Summary instead, replace this line:

// Get 160 characters of the body, strip HTML tags
'content' => strip_tags(substr($node->get('body')->value, 0, 160)) . '...',

... with this:

// Get the summary, without HTML by default
'content' => $node->get('body')->summary

Found in Add meta tag to <head>, thanks to all users who shared their solutions there.

Help improve this page

Page status: Needs review

You can: