How do I correctly cache a themed menu output? In mytheme_preprocess_menu(), I am altering the main menu:

function mytheme_preprocess_menu(&amp;$variables, $hook) {
  $node = \Drupal::routeMatch()-&gt;getParameter('node');
  if ('menu__main' == $hook) {
    if ($node) {
      _mytheme_menu_replace_with_project_items($node, $variables['items']);
    }
  }
}


In _mytheme_menu_replace_with_project_items(), I check whether the current node is a project node, and show that node's submenu instead.

When I visit the node the menu gets displayed, but when I add another node with another project reference, the menu of the former node gets displayed.

How can I correctly cache that?

I tried with the following code, but it didn't work.

$variables['#cache']['tags'][] = 'node:' . $node-&gt;id();
$variables['#cache']['contexts'][] = 'route.name';
$variables['#cache']['contexts'][] = 'theme';
Okay, so this combination worked...

$variables['#cache']['tags'] = ['node:' . $node-&gt;id()];
$variables['#cache']['contexts'] = ['route', 'theme'];
$variables['#cache']['keys'] = ['entity_view', 'node', $node-&gt;id()];


I dont see a huge difference to my first attempt but whatever!