Creating a link from node ID in Drupal 8

Nicensin picture Nicensin · Feb 14, 2016 · Viewed 35.4k times · Source

I am checking out Drupal 8 and try to generate a link based on the node ID of an article. In Drupal 7 it is something like:

$options = array('absolute' => TRUE);
$nid = 1; // Node ID
$url = url('node/' . $nid, $options);

This results into an absolute link with the correct url-alias.

So the url()-function seems to be deprecated; what is the Drupal-8 way? Looks like a really basic function for me but I could not find any useful references.

Answer

Pierre Buyle picture Pierre Buyle · Feb 15, 2016

You need to use the \Drupal\Core\Url class, specifically its fromRoute static method. Drupal 8 uses routes which have name different from their actual URL path. In your case, the route to use is the canonical route for a node entity: entity.node.canonical. \Drupal\Core\Url::fromRoute() will not return a string, but an object. To get the URL as a string, you need to call its toString() method.

$options = ['absolute' => TRUE];
$url = \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 1], $options);
$url = $url->toString();

The static method is not easily testable, $url->toString() require an initialized container. Your can replace the static method with a call to UrlGeneratorInterface::generateFromRoute() on the url_generator service.

$options = ['absolute' => TRUE];
$url = $this->url_generator->generateFromRoute('entity.node.canonical', ['node' => 1], $options);
$url = $url->toString();

Unfortunately, this method is marked as @internal so you are not supposed to use it in user code (ie. outside Drupal core).