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

Schema Breadcrumb Bundle Laravel Package

exs/schema-breadcrumb-bundle

Symfony bundle that generates schema.org BreadcrumbList JSON-LD script tags from Twig. Pass an ordered array of breadcrumb items with name, URL, and optional image to the getJsonBreadcrumb() function to output valid structured data for search engines.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Despite the "Laravel/PHP package" framing, exs/schema-breadcrumb-bundle is a Symfony bundle, not a Laravel package. It is built for the legacy AppKernel::registerBundles() registration model (Symfony 2.x/3.x era) and exposes a Twig global function getJsonBreadcrumb(). It ships no service provider, no facade, no config publishing, and no package auto-discovery — so it cannot be dropped into a Laravel application as distributed. The architectural fit for Laravel is effectively zero. The mitigating factor is that the actual work — serializing an ordered array of {name, url, image} items into a schema.org BreadcrumbList JSON-LD <script> block — is a pure-PHP concern with no framework coupling. The capability is portable; the package is not.

Integration feasibility. Low technical effort, but it is a fork-and-own / reimplement operation rather than a composer require. The extraction is one or two small classes plus JSON encoding and escaping logic — on the order of half a day to a day to lift into a Laravel Blade component or View\Component, including tests. Attempting to install the bundle itself into Laravel will fail or pin the platform on Symfony 2/3 components, Twig 1.x, and PHP 5.5–7.0-era constraints.

Technical risk. The headline risk is abandonment, not complexity: 0 stars, 0 dependents, a Travis CI badge (a CI service effectively deprecated for OSS), no visible release history, no test suite, no security policy. That means no upstream fixes, no PHP 8.x / modern-framework compatibility, and no CVE response process. The functional risk surface is small and well-bounded: JSON encoding, output escaping inside a <script> context, and schema.org conformance. The concrete risks are (a) XSS/script-injection via unescaped name/url/image values, (b) json_encode silently returning false on invalid UTF-8 and emitting a broken tag, and (c) malformed or relative URLs producing Google Rich Results validation errors. All three are addressable with a small, well-tested internal implementation.

Key questions.

  • Is the target actually Laravel (Blade, service container), or a legacy Symfony app? The answer flips the recommendation from "reimplement" to "possibly use as-is."
  • What PHP/framework versions does composer.json pin, and does it install anywhere on the current stack?
  • Does it escape breadcrumb values before embedding, or rely on the caller? (Assume unescaped until proven otherwise.)
  • Are there tests or fixtures defining ListItem position numbering and item-omission rules?
  • Is optional image support actually required, or is name + URL sufficient?
  • Why this over spatie/schema-org (Laravel-native, maintained, supports schema graphs) or a ~50-line in-house builder?

Integration Approach

Stack fit. Poor for Laravel out of the box; acceptable only for a legacy Symfony 3 codebase already using kernel registration. The Twig global function is a hard friction point because Laravel templates are Blade — the package provides no equivalent.

Migration path. Two viable routes; neither is the literal "install and wrap":

  1. Adopt a maintained equivalent (preferred). spatie/schema-org is Laravel-native, supports BreadcrumbList/ListItem, is actively maintained, and composes with other schema types (Organization, Product, Article, FAQPage) you will inevitably need — which this bundle cannot do.
  2. Internalize the logic (fallback). Vendor the generation semantics into a small App\Support\StructuredData\BreadcrumbList builder plus a <x-breadcrumbs-schema :items="..."/> Blade component. Identical output, no dependency, no maintenance/license question.

If the application is genuinely Symfony 2/3 and only needs the script tag, direct use is defensible — but wrap the Twig call and audit output escaping before production given the maturity signals.

Compatibility. Expect the bundle to require Symfony ~2.3|~3.0, Twig ~1.x, and PHP ≤7.x. Assume incompatibility with Laravel 9/10/11 and PHP 8.2+. Any path using the bundle on a modern stack needs a shim or hard fork — at which point the in-house option is cheaper.

Sequencing.

  1. Confirm target framework and PHP version; if Laravel, drop the bundle from consideration immediately.
  2. Decide build-vs-adopt (spatie vs. internal component) based on whether other structured-data types are on the roadmap.
  3. Define a breadcrumb DTO (name, absolute url, optional image, explicit position) so ordering is not implicit in array order — the README's array-order-as-hierarchy is a fragility to eliminate.
  4. Emit JSON-LD with strict output escaping and JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR.
  5. Add feature tests asserting the tag parses as valid JSON and matches the expected schema.org shape; validate manually via Google's Rich Results Test.
  6. Roll out to a low-traffic template first, verify in Search Console, then propagate to all breadcrumb-bearing pages.

Operational Impact

Maintenance. As a third-party dependency, operational burden is unsustainable: no maintainer means every PHP upgrade, framework upgrade, or security advisory becomes our problem with no upstream path. As an internalized component, maintenance is a small, predictable surface we fully control — the honest trade. TPM recommendation: do not carry the dependency; own ~50 lines of code.

Support. No community, no dependents, no issue history to lean on. Any defect must be diagnosed internally from source. There is no vendor SLA and effectively no support channel beyond reading the code.

Scaling. Emitting a <script> block per page template is trivial at any traffic volume — this is render-time serialization, not a service. The real scaling concern is governance: a one-script-per-schema-type pattern becomes hard to validate and maintain as you add Organization, Product, and Article markup. A single JSON-LD @graph strategy (via spatie/schema-org or a custom builder) scales far better across a growing content surface.

Failure modes. (1) Unescaped values inject into the script block — XSS risk, must be closed before any production use. (2) json_encode returns false on invalid UTF-8, silently dropping the tag with no signal — use JSON_THROW_ON_ERROR and handle it. (3) Array order drift breaks position numbering silently — mitigate with an explicit DTO carrying position. (4) Relative or non-canonical URLs fail Rich Results validation and erode SEO value. (5) Abandoned upstream yields no fix when the platform moves on.

Ramp-up. Near-zero learning curve: the README is a single example and the domain knowledge (schema.org BreadcrumbList, JSON-LD) is well-documented by the spec and Google. Any engineer can reimplement it in an afternoon; the effort goes into doing it correctly (escaping, encoding, URL canonicalization, validation), not in understanding the package. The team should budget the day for a properly tested internal component and treat the package strictly as a behavioral reference.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager