In Drupal 8.4, I am trying to add a class to the body (like Drupal 7 had) when the page viewed is a node (or entity for that matter), something like [entity]-[create or edit], so that, when a user is editing or creating a node, a class like page-node-edit gets added to the body classes array.


You can use hook_preprocess_page and check the current route:

function mymodule_preprocess_page(&$vars) {

  $route_name = \Drupal::routeMatch()->getRouteName();

  // This would add a class based on the route.  You'd need the 
  // pathauto module enabled.
  $vars['page_classes'][] = \Drupal::service('pathauto.alias_cleaner')->cleanString($route_name);

  // This would add the classes asked for in the question.
  if ($route_name == 'entity.node.edit_form') {
    $vars['page_classes'][] = 'entity-edit';
  elseif ($route_name == 'node.add') {
    $vars['page_classes'][] = 'entity-create';
  • Any way to use function THEMENAME_preprocess_html like in d7? – ymdahi Oct 22 '17 at 0:28
  • Tried this for myself and it didn't work. There should be a way of doing this in the theme, but am unable to discover how. Was easy in D7 when we could use arg with an if statement to target the page via the url... – sbdc May 6 '18 at 18:28

I couldn't get oknate's solution to work so I modified it. You can add it to your custom module file.

 * Implements hook_preprocess_html().
function MYMODULE_preprocess_html(&$variables) {
  // Add node ID
  if ($node = \Drupal::request()->attributes->get('node')) {
   $variables['attributes']['class'][] = 'page-node-' . $node->id();

  // Get route
  $route_name = \Drupal::routeMatch()->getRouteName();

  // Add edit class
  if ($route_name == 'entity.node.edit_form') {
    $variables['attributes']['class'][] = 'entity-edit';

  // Add create class
  if ($route_name == 'node.add') {
    $variables['attributes']['class'][] = 'entity-create';


After dealing with this for some time, I've found a potential alternative way of approaching this sort of functionality.

For my use case, I was trying to add classes to the body of the node add/edit pages, so I can do things like hide blocks and alter positioning using css.

My new approach to achieve this is to simply override the page.html.twig. So, if I wanted to customize the node edit/add pages for a content type called "Blog Post", I would create two new template files:

  1. page--node--add--blogpost.html.twig
  2. page--node--edit--blogpost.html.twig

Note that I can create one set template files to cover all content types like so:

  1. page--node--add.html.twig
  2. page--node--edit.html.twig

I can also override html.html.twig, if I really needed to get my classes into the node add/edit pages. For this approach, I would create two new template pages:

  1. html--node--add.html.twig
  2. html--node--edit.html.twig

In these template pages, I would simply modify the body_classes array like so:

  set body_classes = [
    logged_in ? 'user-logged-in',
    not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
    node_type ? 'page-node-type-' ~ node_type|clean_class,
    db_offline ? 'db-offline',
    theme.settings.navbar_position ? 'navbar-is-' ~ theme.settings.navbar_position,
    theme.has_glyphicons ? 'has-glyphicons',
function MYTHEME_preprocess_html(&$variables) {
$current_path = \Drupal::service('path.current')->getPath();
$path_alias = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);
$is_edit = strpos($path_alias, '/edit');
if ($is_edit !== false) {
  $edit_css_classname = $variables['node_type'].'-edit';
  $variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($edit_css_classname);

This code snippet adds a MY-NODE-TYPE-edit class to the body tag of a page, if there is "/edit" inside the path.

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.