How do I create custom user tabs? I am trying to create a new custom tab that appears on all routes that are descendants of entity.{entity_type}.canonical. I have tried extending the DeriverBase class, specifically overriding the getDerivativeDefinitions method. I created the tab itself by extending LocalTaskDefault and overriding the getRouteParameters method. The tab appears when you visit a standard Drupal user path such as www.mysite.com/user/1/ or www.mysite.com/user/1/edit. However, when we add our new custom user routes such as www.mysite.com/user/1/subscribe, no tabs appear. Is there a special way to define local menu tasks on custom routes? A sample of the code:

 $this-&gt;derivatives['recurly.subscription_tab'] = [
  'title' =&gt; $this-&gt;t('Subscription'),
  'weight' =&gt; 5,
  'route_name' =&gt; 'recurly.subscription_list',
  'base_route' =&gt; "entity.$entity_type.canonical",
];

foreach ($this-&gt;derivatives as &amp;$entry) {
  $entry += $base_plugin_definition;
}


Thanks in advance of any help.
As suggested by Berdir you can look at Devel module and at how it's implementing that. The following code was "extracted" from Devel

1) Create the routes

Create the file mymodule.routing.yml in and inside define a route callback (which is used for create the dynamic routes)

route_callbacks:
  - '\Drupal\mymodule\Routing\MyModuleRoutes::routes'


Create the class MyModuleRoutes for generate yours dynamic routes in src/Routing

&lt;?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class MyModuleRoutes implements ContainerInjectionInterface {

  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this-&gt;entityTypeManager = $entity_type_manager;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container-&gt;get('entity_type.manager')
    );
  }

  public function routes() {
    $collection = new RouteCollection();

    foreach ($this-&gt;entityTypeManager-&gt;getDefinitions() as $entity_type_id =&gt; $entity_type) {
      if ($entity_type-&gt;hasLinkTemplate('canonical')) {
        $route = new Route("/mymodule/$entity_type_id/{{$entity_type_id}}");
        $route
          -&gt;addDefaults([
            '_controller' =&gt; '\Drupal\mymodule\Controller\MyModuleController::doStuff',
            '_title' =&gt; 'My module route title',
          ])
          -&gt;addRequirements([
            '_permission' =&gt; 'access mymodule permission',
          ])
          -&gt;setOption('_mymodule_entity_type_id', $entity_type_id)
          -&gt;setOption('parameters', [
            $entity_type_id =&gt; ['type' =&gt; 'entity:' . $entity_type_id],
          ]);

        $collection-&gt;add("entity.$entity_type_id.mymodule", $route);
      }
    }

    return $collection;
  }

}


2) Create the dynamic local tasks

Create the file mymodule.links.task.yml and inside define a deriver

mymodule.tasks:
  class: \Drupal\Core\Menu\LocalTaskDefault
  deriver: \Drupal\mymodule\Plugin\Derivative\MyModuleLocalTasks


Create the class MyModuleLocalTasks for generate yours dynamic routes in src/Plugin/Derivative

&lt;?php

namespace Drupal\mymodule\Plugin\Derivative;

use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyModuleLocalTasks extends DeriverBase implements ContainerDeriverInterface {

  protected $entityTypeManager;

  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this-&gt;entityTypeManager = $entity_type_manager;
  }

  public static function create(ContainerInterface $container, $base_plugin_id) {
    return new static(
      $container-&gt;get('entity_type.manager')
    );
  }

  public function getDerivativeDefinitions($base_plugin_definition) {
    $this-&gt;derivatives = array();

    foreach ($this-&gt;entityTypeManager-&gt;getDefinitions() as $entity_type_id =&gt; $entity_type) {
      if ($entity_type-&gt;hasLinkTemplate('canonical')) {
        $this-&gt;derivatives["$entity_type_id.mymodule_tab"] = [
          'route_name' =&gt; "entity.$entity_type_id.mymodule",
          'title' =&gt; t('Mymodule title'),
          'base_route' =&gt; "entity.$entity_type_id.canonical",
          'weight' =&gt; 100,
        ] + $base_plugin_definition;
      }
    }

    return $this-&gt;derivatives;
  }

}


3) Create the controller

Create the class MyModuleController in src/Controller
    

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;

class MyModuleController extends ControllerBase {

  public function doStuff(RouteMatchInterface $route_match) {
    $output = [];

    $parameter_name = $route_match-&gt;getRouteObject()-&gt;getOption('_mymodule_entity_type_id');
    $entity = $route_match-&gt;getParameter($parameter_name);

    if ($entity &amp;&amp; $entity instanceof EntityInterface) {
      $output = ['#markup' =&gt; $entity-&gt;label()];
    }

    return $output;
  }

}