diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 96a75da78a..e95c01b2c8 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -269,6 +269,7 @@ public function buildMultiple(array $build_list) {
         $this->moduleHandler()->invokeAll($view_hook, [&$build_list[$key], $entity, $display, $view_mode]);
         $this->moduleHandler()->invokeAll('entity_view', [&$build_list[$key], $entity, $display, $view_mode]);
 
+        $this->addContextualLinks($build_list[$key], $entity);
         $this->alterBuild($build_list[$key], $entity, $display, $view_mode);
 
         // Assign the weights configured in the display.
@@ -324,6 +325,36 @@ public function buildComponents(array &$build, array $entities, array $displays,
     }
   }
 
+  /**
+   * Add contextual links.
+   *
+   * @param array $build
+   *   The render array that is being created.
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to be prepared.
+   */
+  protected function addContextualLinks(array &$build, EntityInterface $entity) {
+    if ($entity->isNew()) {
+      return;
+    }
+    $key = $entity->getEntityTypeId();
+    $rel = 'canonical';
+    if ($entity instanceof ContentEntityInterface && !$entity->isDefaultRevision()) {
+      $rel = 'revision';
+      $key .= '_revision';
+    }
+    if ($entity->hasLinkTemplate($rel)) {
+      $build['#contextual_links'][$key] = [
+        'route_parameters' => $entity->toUrl($rel)->getRouteParameters(),
+      ];
+      if ($entity instanceof EntityChangedInterface) {
+        $build['#contextual_links'][$key]['metadata'] = [
+          'changed' => $entity->getChangedTime(),
+        ];
+      }
+    }
+  }
+
   /**
    * Specific per-entity building.
    *
diff --git a/core/modules/block_content/src/BlockContentViewBuilder.php b/core/modules/block_content/src/BlockContentViewBuilder.php
index 29c668cd63..2ea321d769 100644
--- a/core/modules/block_content/src/BlockContentViewBuilder.php
+++ b/core/modules/block_content/src/BlockContentViewBuilder.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\block_content;
 
-use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
 
@@ -41,18 +40,4 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
     return $build;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
-    parent::alterBuild($build, $entity, $display, $view_mode);
-    // Add contextual links for this custom block.
-    if (!$entity->isNew()) {
-      $build['#contextual_links']['block_content'] = [
-        'route_parameters' => ['block_content' => $entity->id()],
-        'metadata' => ['changed' => $entity->getChangedTime()],
-      ];
-    }
-  }
-
 }
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php b/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php
new file mode 100644
index 0000000000..e4e1a48ac8
--- /dev/null
+++ b/core/modules/block_content/tests/src/Functional/BlockContentContextualLinksTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\Tests\block_content\Functional;
+
+/**
+ * Tests views contextual links on block content.
+ *
+ * @group block_content
+ */
+class BlockContentContextualLinksTest extends BlockContentTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'contextual',
+  ];
+
+  /**
+   * Tests contextual links.
+   */
+  public function testBlockContentContextualLinks() {
+    $block_content = $this->createBlockContent();
+
+    $block = $this->placeBlock('block_content:' . $block_content->uuid());
+
+    $user = $this->drupalCreateUser([
+      'administer blocks',
+      'access contextual links',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->drupalGet('<front>');
+    $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'block:block=' . $block->id() . ':langcode=en|block_content:block_content=' . $block_content->id() . ':');
+  }
+
+}
diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php
index f0971fb3bb..2bb7f4a2af 100644
--- a/core/modules/node/src/NodeViewBuilder.php
+++ b/core/modules/node/src/NodeViewBuilder.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\node;
 
-use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
 use Drupal\node\Entity\Node;
@@ -141,29 +140,4 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
-    /** @var \Drupal\node\NodeInterface $entity */
-    parent::alterBuild($build, $entity, $display, $view_mode);
-    if ($entity->id()) {
-      if ($entity->isDefaultRevision()) {
-        $build['#contextual_links']['node'] = [
-          'route_parameters' => ['node' => $entity->id()],
-          'metadata' => ['changed' => $entity->getChangedTime()],
-        ];
-      }
-      else {
-        $build['#contextual_links']['node_revision'] = [
-          'route_parameters' => [
-            'node' => $entity->id(),
-            'node_revision' => $entity->getRevisionId(),
-          ],
-          'metadata' => ['changed' => $entity->getChangedTime()],
-        ];
-      }
-    }
-  }
-
 }
diff --git a/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php b/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php
new file mode 100644
index 0000000000..0d4aabe6a0
--- /dev/null
+++ b/core/modules/node/tests/src/Functional/NodeContextualLinksTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\Tests\node\Functional;
+
+use Drupal\node\Entity\Node;
+
+/**
+ * Tests views contextual links on nodes.
+ *
+ * @group node
+ */
+class NodeContextualLinksTest extends NodeTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'contextual',
+  ];
+
+  /**
+   * Tests contextual links.
+   */
+  public function testNodeContextualLinks() {
+    // Create a node item.
+    $node = Node::create([
+      'type' => 'article',
+      'title' => 'Unnamed',
+    ]);
+    $node->save();
+
+    $user = $this->drupalCreateUser([
+      'administer nodes',
+      'access contextual links',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->drupalGet('node/' . $node->id());
+    $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'node:node=' . $node->id() . ':');
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php
index 2e70a1cf7d..b8eac0acc3 100644
--- a/core/modules/taxonomy/src/Entity/Term.php
+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -19,7 +19,7 @@
  *   handlers = {
  *     "storage" = "Drupal\taxonomy\TermStorage",
  *     "storage_schema" = "Drupal\taxonomy\TermStorageSchema",
- *     "view_builder" = "Drupal\taxonomy\TermViewBuilder",
+ *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
  *     "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
  *     "access" = "Drupal\taxonomy\TermAccessControlHandler",
  *     "views_data" = "Drupal\taxonomy\TermViewsData",
diff --git a/core/modules/taxonomy/src/TermViewBuilder.php b/core/modules/taxonomy/src/TermViewBuilder.php
index 6748a4b03c..07d0c078f2 100644
--- a/core/modules/taxonomy/src/TermViewBuilder.php
+++ b/core/modules/taxonomy/src/TermViewBuilder.php
@@ -2,24 +2,17 @@
 
 namespace Drupal\taxonomy;
 
-use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
-use Drupal\Core\Entity\EntityInterface;
+@trigger_error(__NAMESPACE__ . '\TermViewBuilder is deprecated in Drupal 8.5.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityViewBuilder instead. See https://www.drupal.org/node/2924233.', E_USER_DEPRECATED);
+
 use Drupal\Core\Entity\EntityViewBuilder;
 
 /**
  * View builder handler for taxonomy terms.
+ *
+ * @deprecated in Drupal 8.5.x and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Core\Entity\EntityViewBuilder instead.
+ *
+ * @see \Drupal\Core\Entity\EntityViewBuilder
+ * @see https://www.drupal.org/node/2924233
  */
-class TermViewBuilder extends EntityViewBuilder {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
-    parent::alterBuild($build, $entity, $display, $view_mode);
-    $build['#contextual_links']['taxonomy_term'] = [
-      'route_parameters' => ['taxonomy_term' => $entity->id()],
-      'metadata' => ['changed' => $entity->getChangedTime()],
-    ];
-  }
-
-}
+class TermViewBuilder extends EntityViewBuilder {}
diff --git a/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php b/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php
new file mode 100644
index 0000000000..997e698b9e
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Functional/TermContextualLinksTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Functional;
+
+/**
+ * Tests views contextual links on terms.
+ *
+ * @group taxonomy
+ */
+class TermContextualLinksTest extends TaxonomyTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'contextual',
+  ];
+
+  /**
+   * Tests contextual links.
+   */
+  public function testTermContextualLinks() {
+    $vocabulary = $this->createVocabulary();
+    $term = $this->createTerm($vocabulary);
+
+    $user = $this->drupalCreateUser([
+      'administer taxonomy',
+      'access contextual links',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->drupalGet('taxonomy/term/' . $term->id());
+    $this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'taxonomy_term:taxonomy_term=' . $term->id() . ':');
+  }
+
+}
