Overwrite the url function of a specific node entity
Entity URI callback

You can implement an URI callback. Example in comment.module:

/**
 * Entity URI callback.
 */
function comment_uri(CommentInterface $comment) {
  return new Url(
    'entity.comment.canonical',
    [
      'comment' =&gt; $comment-&gt;id(),
    ],
    ['fragment' =&gt; 'comment-' . $comment-&gt;id()]
  );
}


and add the callback to the annotations of the entity type:

*   uri_callback = "comment_uri",


For an existing entity use a hook_entity_type_alter().

Bundle specific URI callback

A URI callback for a specific content type can be defined in the bundle definitions:

**
 * Implements hook_entity_bundle_info_alter().
 */
function mymodule_entity_bundle_info_alter(&amp;$bundles) {
  if (isset($bundles['node']['my_content_type'])) {
    $bundles['node']['my_content_type']['uri_callback'] = 'my_content_type_uri';
  }
}


The callback:

/**
 * Bundle URI callback.
 */
function my_content_type_uri(NodeInterface $node) {
  // build a url object $url
  return $url;
}


A bundle-specific callback takes precedence over the generic one for the entity type and a link template (defined in the links array of the entity type) takes precedence over both, so you need to remove the link template if you want to override an existing one, e.g. canonical, which makes you responsible to provide the route needed for the custom url, if it was built before by a route provider and is not defined in a *.routing.yml file.



Edit:

To modify the url in links to a specific content type you can use a hook_link_alter():

function mymodule_link_alter(&amp;$variables) {
  $url = $variables['url'];
  if ($url-&gt;isRouted() &amp;&amp; $url-&gt;getRouteName() == 'entity.node.canonical') {
    if (isset($variables['options']['entity'])) {
      $node = $variables['options']['entity'];
      if ($node-&gt;bundle() == 'article') {
        // modify the links to articles
      }
    }
  }
}