Getting parent menu links of the current node

By nnevill, 6 February, 2023

This mostly needed for breadcrumbs or for adding some specific navigation components like link to top menu item in case of very nested menu tree. So here is code:
 

/**
 * Get parent menu links for current node.
 *
 * @param \Drupal\node\NodeInterface $node
 *   Node entity.
 * @param string $menu
 *   Menu machine name
 *
 * @return array
 *   Either empty array or array with parent links.
 */
function get_parent_menu_links($node, $menu = 'main'): array {
  $parent_links = [];

  // Loading needed services.
  $active_trail = \Drupal::service('menu.active_trail');
  $menu_link_manager = \Drupal::service('plugin.manager.menu.link');

  // Getting menu link entity from current route.
  $menu_links = $menu_link_manager->loadLinksByRoute('entity.node.canonical', array('node' => $node->id()));
  if ($menu_links) {
    $menu_link = reset($menu_links);
    // We need this to avoid having current node link in parent links array.
    $current_plugin_id = $menu_link->getPluginId();

    // Getting active trail array.
    $trail_ids = $active_trail->getActiveTrailIds($menu);
    foreach (array_reverse($trail_ids) as $value) {
      if ($value && $value !== $current_plugin_id) {
        $link_instance = $menu_link_manager->createInstance($value);
        $parent_links[] = [
          'title' => $link_instance->getTitle(),
          'url' => $link_instance->getUrlObject()->toString(),
        ];
      }
    }
  }

  return $parent_links;
}