Change record status: 
Project: 
Introduced in branch: 
8.0.x
Introduced in version: 
8.0.0-BETA11
Description: 

The problem

When generating URLs (and thus also when generating links, which are URLs wrapped in <a> tags), Drupal applies "outbound path processing" and "outbound route processing". This means that the generated URLs/links depend on request context as well, and thus the outbound path/route processors affect cacheability of the generated URLs/links.

Examples include adding CSRF query parameters for routes that need CSRF tokens, and the language prefix for multilingual sites.

The solution

Ensure the necessary bubbleable metadata (which contains cacheability metadata + attachments to be bubbled, so e.g. placeholders, asset libraries…) is present.

For themers generating URLs/links
No changes: Twig's link(), url() and url_from_path() functions now bubble the necessary cacheability metadata too, but you don't have to even think about that.
For developers using the URLgenerator or Url::toString() directly
  1. \Drupal\Core\Routing\UrlGeneratorInterface::generateFrom(Route|Path)() have a new optional parameter: $collect_bubbleable_metadata = FALSE. The default value of FALSE means no bubbleable metadata is returned. When it is set to TRUE, a GeneratedUrlobject is returned. This is a subclass of BubbleableMetadata (to store cacheability metadata), with one addition: it also stores the generated URL.
  2. The procedural alias for this — \Drupal::url() — has the same changes.
  3. \Drupal\Core\Url::toString() has also gained this optional parameter. Usually, URLs are rendered as links. Then #type => link takes care of things. But, it is entirely possible to use $url->toString() while generating a render array, and in that case, cacheability metadata should be collected. This is added for those use cases. Also: #type => link uses LinkGenerator, which uses $url->toString().
For developers using the link generator
  1. LinkGeneratorInterface::generate(FromLink)() always GeneratedLink object. The GeneratedLink object implements MarkupInterface and therefore can be passed directly to the template layer and rendered safely. Note, if code previously manipulated the output of the link generator using string functions read the CR which documents similar change for translated string: https://www.drupal.org/node/2564451
  2. The procedural alias for this — \Drupal::l() — has the same changes.
For developers writing outbound path/route processors
\Drupal\Core\PathProcessor\OutboundPathProcessorInterface::processOutbound and \Drupal\Core\RouteProcessor\OutboundRouteProcessorInterface::processOutbound() have a new optional parameter: BubbleableMetadata $bubbleable_metadata. Implementations of this interface can thus append their cacheability metadata to resulting path/route.
Impacts: 
Module developers
Themers