Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Breadcrumb Widget Laravel Package

victoire/breadcrumb-widget

A Laravel widget for rendering configurable breadcrumb trails from your app's routes and pages. Define crumbs in PHP, output accessible markup, and drop them into Blade layouts with a simple directive.

View on GitHub
Deep Wiki
Context7

Getting Started

This is not a Laravel package — it is a Symfony bundle for the Victoire CMS, a Symfony-based content management platform that ships its own "widget" system. If you are working in a Laravel codebase there is nothing to composer require here; treat this assessment as a reference for how a breadcrumb widget is meant to be wired, not as an install guide for your app.

If you actually are on a legacy Victoire/Symfony project:

  1. Check compatibility before anything else. Look at the repo's composer.json and the last tag (2019-04-29). Expect symfony/* constraints in the ^2.8 || ^3.x range and PHP ^7.x. If your app is on Symfony 5/6 or PHP 8, install will fail or, worse, resolve and break at runtime.
  2. Install:
    composer require victoire/breadcrumb-widget
    
  3. Register the bundle alongside the other VictoireWidget*Bundle entries:
    • Symfony 3: app/AppKernel.php → new Victoire\Widget\BreadcrumbBundle\VictoireWidgetBreadcrumbBundle(),
    • Symfony 4-style config/bundles.php if the project was migrated.
  4. Refresh caches and assets, since widget bundles usually register a form type, a Twig namespace, and sometimes translations:
    bin/console cache:clear
    bin/console assets:install --symlink
    
  5. First use case: open a Victoire page in the backend editor, add a "Breadcrumb" widget to a page slot, save, and confirm it renders on the front. That single round-trip tells you whether the bundle's service registration and Twig namespace are intact.

Where to look first in the source: Resources/views/ (the rendering template), the widget's Entity/ or Widget/ class (what fields are configurable), the Form/ type (what the editor UI exposes), and composer.json (the real compatibility story). With 2 stars and 0 dependents there is no documentation site and no community Q&A — the code is the documentation.

Implementation Patterns

Rely on route/menu context rather than hand-authored trails. The durable pattern is to derive the breadcrumb from the request's route hierarchy or from the same menu tree the site navigation uses. Hardcoded item lists inside the widget drift out of sync the moment an editor renames or re-parents a page. If the bundle exposes a items collection, populate it from a resolver service, not from editor input.

Override the Twig template in your app, don't fork the bundle. Widget bundles conventionally expose templates under a VictoireWidgetBreadcrumbBundle: namespace. Copy the template into app/Resources/.../views/ (or templates/bundles/... on newer Symfony) and edit the copy. This is the one extension point that survives an abandoned dependency: template overrides are upgrade-safe, PHP class overrides are not.

Separate "structure" from "presentation" in the widget config. Editors typically want to control: whether the home crumb is shown, the separator glyph, and whether the current page is linked. Keep those as widget form fields; keep the trail itself computed. Mixing the two makes the widget unusable across more than one template.

Emit structured data at the same time as the markup. A breadcrumb whose only consumer is CSS is half-useful. Render BreadcrumbList JSON-LD from the same item array you render as <ol>/<ul> — one source of truth, two outputs:

<nav aria-label="breadcrumb">
  <ol class="breadcrumb">
    {% for item in items %}
      <li class="breadcrumb__item{{ loop.last ? ' is-current' }}">
        {% if not loop.last and item.url %}
          <a href="{{ item.url }}">{{ item.label }}</a>
        {% else %}
          <span aria-current="page">{{ item.label }}</span>
        {% endif %}
      </li>
    {% endfor %}
  </ol>
</nav>

Cache the computed trail, keyed on route + locale. Breadcrumb assembly is cheap per-request but easy to cache aggressively because it changes only on content edits. Key on route + params + _locale; invalidate on page save (Victoire page entities usually give you a post-persist hook).

Fallbacks belong in the resolver, not the template. If a page has no parent chain (orphaned node, 404, or a dynamically-routed detail page), return [home, current] from the resolver service. Doing it in Twig guarantees you'll forget one template.

Compose, don't duplicate. Place the breadcrumb widget in the page layout slot rather than per-page; otherwise every new page needs an editor to remember to add it, and the trail becomes inconsistent across the site.

If you're porting the idea to Laravel, the mapping is direct: a BreadcrumbService resolving from Route::current() plus a parent chain, a Blade component for the markup, Cache::remember() on the trail, and a BreadcrumbList JSON-LD partial. You will write this in an afternoon; adapting this Symfony bundle to Laravel is not a thing.

Gotchas and Tips

  • Abandoned since 2019-04-29. No security patches, no PHP 8 compatibility, no Symfony 5+. Audit composer.json and the dependency tree before letting this into anything that faces the internet. If it already installed cleanly, pin the lockfile and treat it as frozen.
  • 2 stars / 0 dependents means zero bus factor. There is no one to ask, no Stack Overflow corpus, no issue triage. Budget for reading the source yourself; assume any bug you hit is yours to fix via a fork or a local patch (repositories with a VCS entry pointing at your fork is the practical route).
  • Widget not appearing in the editor is almost always registration, not the widget. Check the bundle is in the kernel/bundles.php, then cache:clear. Widget discovery in Victoire is cache-driven; a stale cache looks identical to a missing bundle.
  • Template changes require a cache clear in prod and often an assets:install if you added CSS. In dev a stale Twig cache after renaming a block is a classic 20-minute detour.
  • The last crumb must not be a link. It's the current page; linking it is a common accessibility and SEO regression. Also mark it aria-current="page".
  • Use absolute URLs in JSON-LD, relative in markup. Structured data validators reject relative item values; browsers don't care about the <a href>.
  • Trailing-slash and locale-prefix mismatches silently produce breadcrumb links that redirect. Build URLs from the router (generateUrl) rather than concatenating path segments.
  • Multi-locale sites: the trail label should come from the translated page title, not the raw slug. If the widget echoes the URL segment, German pages get English-looking crumbs.
  • Debugging a broken render: enable the profiler, find the widget's controller/service in the victoire_widget tagged services (bin/console debug:container --tag=victoire.widget), and dump the items array before it reaches Twig. The failure is nearly always an empty item collection, not a template error.
  • Extension points, in order of safety: (1) template override, (2) a decorator on the trail-resolver service, (3) form-type extension to add fields, (4) forking the bundle. Do not patch vendor/ directly — the next composer install erases it.
  • Don't rely on the widget's editor form for structured data or SEO toggles. Anyone with editor access can break your rich results. Keep SEO-affecting output in the template/service layer where developers control it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator