Creating breadcrumbs in Drupal 8

A really easy to use API

This article was originally posted at Medium

A breadcrumb or breadcrumb trail is a graphical control element frequently used as a navigational aid in user interfaces and on web pages. (Wikipedia)

Breadcrumbs have become a service in Drupal 8; so, in order to customize the breadcrumbs programatically, you need to create a breadcrumb_builder service and define when your service class applies to create the breadcrumbs and actually build the breadcrumbs using the interfaces and functions provided by the API.

Assuming you have a content type named blog and a taxonomy vocabulary named category, you want all blog post to have a breadcrumb like this: Home -> Category -> Blog Title. Let's do it! We'll use a module named demo_module

The first thing you need to do is to define the service. In order to do this, you need a file with a content like this:

    class: Drupal\demo_module\BreadcrumbsBuilder
    arguments: ['@current_user', '@access_manager']
      - { name: breadcrumb_builder, priority: 100 }

The only other thing that you need to create is obviously the BreadcrumbsBuilder class. Given the class name we gave in the service definition, you need a file named BreadcrumbsBuilder.php under src folder with content like this:

namespace Drupal\demo_module;
use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class BreadcrumbsBuilder implements BreadcrumbBuilderInterface {
  use StringTranslationTrait;
   * The access manager.
   * @var \Drupal\Core\Access\AccessManagerInterface
  protected $accessManager;
   * The user currently logged in.
   * @var \Drupal\Core\Session\AccountInterface
  protected $currentUser;
   * {@inheritdoc}
  public function __construct(AccountInterface $current_user, AccessManagerInterface $access_manager) {
    $this->currentUser = $current_user;
    $this->accessManager = $access_manager;
  public function applies(RouteMatchInterface $route_match) {
    if ($node = $route_match->getParameter('node')) {
      return TRUE;
    return FALSE;
  public function build(RouteMatchInterface $route_match) {
    $breadcrumb = new Breadcrumb();
    $access = $this->accessManager->check($route_match, $this->currentUser, NULL, TRUE);
    $node = $route_match->getParameter('node');
    $links = [];
    $links[] = Link::createFromRoute($node->label(), '<none>');
    $term = $node->field_category->entity;
    $links[] = Link::createFromRoute($term->label(), 'entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()]);
    $links[] = Link::createFromRoute($this->t('Home'), '<front>');
    return $breadcrumb->setLinks(array_reverse($links));

Besides constructor (where you do all the usual handle of dependency injection), you have two important functions: applies and build.

In applies() you should return a boolean indicating whether your breadcrumb builder applies or not to the given context. In our case, it applies to all nodes in our installation (let's assume it's a very small site only used as a blog).

In build(), you need to create the breadcrumb. It's recommended to add cache metadata (we do that in first lines in the function). Then, you should create a links array and set those links to the created Breadcrumb object using the function setLinks (we use array_reverse to have the breadcrumbs in the expected order).

And that's all! Enjoy your breadcrumbs by placing the breadcrumbs block in your site.

Hide Image
Submitted by kporras07 on Fri, 03/15/2019 - 22:47