In previous versions, Drupal added various <link> tags to the header of nodes and taxonomy term pages:
<link rel="delete-form" href="https://example.com/node/1/delete" />
<link rel="delete-multiple-form" href="https://example.com/admin/content/node/delete?node=1" />
<link rel="edit-form" href="https://example.com/node/1/edit" />
<link rel="version-history" href="https://example.com/node/1/revisions" />
<link rel="revision" href="https://example.com/node/1" />
Rendering these is expensive and reduced cache hit rates. These links were specific to Drupal, and there are no known uses for these links in the real world, so they have been removed.
The canonical and shortlink relation types are still added to node and taxonomy terms, and this has also been extended to pages of all entity types:
<link rel="canonical" href="https://example.com/node/1" />
<link rel="shortlink" href="https://example.com/node/1" />
Sites that need specific or all relationships can add them back using a hook_entity_view() or hook_page_attachments() hook as well, see the code that was removed from NodeViewController:
foreach ($node->uriRelationships() as $rel) {
$url = $node->toUrl($rel)->setAbsolute(TRUE);
// Add link relationships if the user is authenticated or if the anonymous
// user has access. Access checking must be done for anonymous users to
// avoid traffic to inaccessible pages from web crawlers. For
// authenticated users, showing the links in HTML head does not impact
// user experience or security, since the routes are access checked when
// visited and only visible via view source. This prevents doing
// potentially expensive and hard to cache access checks on every request.
// This means that the page will vary by user.permissions. We also rely on
// the access checking fallback to ensure the correct cacheability
// metadata if we have to check access.
if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) {
// Set the node path as the canonical URL to prevent duplicate content.
$build['#attached']['html_head_link'][] = [
[
'rel' => $rel,
'href' => $url->toString(),
],
TRUE,
];
}
if ($rel == 'canonical') {
// Set the non-aliased canonical path as a default shortlink.
$build['#attached']['html_head_link'][] = [
[
'rel' => 'shortlink',
'href' => $url->setOption('alias', TRUE)->toString(),
],
TRUE,
];
}
}
// Since this generates absolute URLs, it can only be cached "per site".
$build['#cache']['contexts'][] = 'url.site';
// Given this varies by $this->currentUser->isAuthenticated(), add a cache
// context based on the anonymous role.
$build['#cache']['contexts'][] = 'user.roles:anonymous';
See the removed taxonomy_page_attachments_alter() and content_translation_page_attachments(), on how to add links in those hooks.
Similarly, modules/entity types that already did add their own canonical and/or shortlink HTML head links can remove that code now.