As per answers received here, we can implement custom breadcrumb either via module or via HOOK_preprocess_breadcrumb.

Via module:

In custom_breadcrumb.module file


namespace Drupal\custom_breadcrumb;

use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\node\NodeInterface;

 * Class Breadcrumbs.
 * @package Drupal\custom_breadcrumb
class Breadcrumbs implements BreadcrumbBuilderInterface {
  use StringTranslationTrait;

   * {@inheritDoc}
  public function applies(RouteMatchInterface $route_match) {
    return $route_match->getRouteName() == 'entity.node.canonical' && $route_match->getParameter('node') instanceof NodeInterface;

   * {@inheritDoc}
  public function build(RouteMatchInterface $route_match) {
    $node = $route_match->getParameter('node');
    $breadcrumb = new Breadcrumb();

    // By setting a "cache context" to the "url", each requested URL gets it's
    // own cache. This way a single breadcrumb isn't cached for all pages on the
    // site.

    // By adding "cache tags" for this specific node, the cache is invalidated
    // when the node is edited.

    // Add "Home" breadcrumb link.
    $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));

    // Given we have a taxonomy term reference field named "field_tags" and that
    // field has data, add that term as a breadcrumb link.
    if (!empty($node->field_tags->entity)) {
    return $breadcrumb;


and then in custom_breadcrumb.services.yml

    class: Drupal\custom_breadcrumb\Breadcrumbs
      - { name: breadcrumb_builder, priority: 100 }

Via HOOK_preprocess_breadcrumb, as mentioned in the answer here

Both the ways are achievable, but the question is which one should be followed and why as a best practice?

  • preprocess is for theming so ...
    – user21641
    Commented Jun 21, 2017 at 10:13

1 Answer 1


When you build a module which for example provides a new content or entity type you can include a breadcrumb builder, because you might have data fields that the standard breadcrumb builder doesn't know of and you want to process them in your breadcrumbs. An example for this would be Drupal\book\BookBreadcrumbBuilder from the core book module.

When you build a theme and want to modify the breadcrumbs already built by the installed core, contrib and custom modules you use a theme based solution in a preprocess hook.

So best practice depends on which level you are working on. Not a good idea would be in this example if the book module would use a preprocess hook.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.