Weave Code
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

Laravel Breadcrumbs Laravel Package

diglactic/laravel-breadcrumbs

Laravel-style breadcrumbs for your app. Define trails in a single place, render them with built-in or custom templates, and support route-bound crumbs and structured data. Official fork of Dave James Miller’s original Laravel Breadcrumbs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:
    composer require diglactic/laravel-breadcrumbs
    
  2. Define breadcrumbs: Create routes/breadcrumbs.php and define your first breadcrumb trail:
    Breadcrumbs::for('home', function ($trail) {
        $trail->push('Home', route('home'));
    });
    
  3. Render in Blade: Add to your view:
    {{ Breadcrumbs::render('home') }}
    
  4. Publish config (optional):
    php artisan vendor:publish --tag=breadcrumbs-config
    
    Edit config/breadcrumbs.php to customize the view template.

First Use Case

For a blog post page, define dynamic breadcrumbs:

// routes/breadcrumbs.php
Breadcrumbs::for('post', function ($trail, $post) {
    $trail->parent('blog');
    $trail->push($post->title, route('posts.show', $post));
});

Render in Blade:

{{ Breadcrumbs::render('post', $post) }}

Implementation Patterns

Core Workflow

  1. Define Trails: Use Breadcrumbs::for() in routes/breadcrumbs.php to map route names to breadcrumb logic.

    Breadcrumbs::for('admin.users', function ($trail) {
        $trail->parent('admin');
        $trail->push('Users', route('admin.users.index'));
    });
    
  2. Dynamic Data Handling: Pass Eloquent models or arrays to closures for dynamic titles/URLs:

    Breadcrumbs::for('product', function ($trail, $product) {
        $trail->parent('shop');
        $trail->push($product->name, route('products.show', $product));
    });
    
  3. Nested Structures: Use parent() to chain trails or loop through hierarchical data (e.g., categories):

    foreach ($category->ancestors as $ancestor) {
        $trail->push($ancestor->name, route('categories.show', $ancestor));
    }
    
  4. Route-Bound Integration: Name routes consistently (e.g., admin.users.index) and use Breadcrumbs::render() with the same name:

    // routes/web.php
    Route::name('admin.users.index')->get('/admin/users', 'UserController@index');
    
    {{ Breadcrumbs::render(request()->route()->getName()) }}
    

Integration Tips

  • Middleware: Use middleware to set breadcrumbs for specific routes:
    public function handle($request, Closure $next) {
        Breadcrumbs::for('dashboard', function ($trail) {
            $trail->push('Dashboard', route('dashboard'));
        });
        return $next($request);
    }
    
  • Service Providers: Register breadcrumbs in boot() for global access:
    public function boot() {
        Breadcrumbs::for('home', function ($trail) {
            $trail->push('Home', route('home'));
        });
    }
    
  • API Responses: Return breadcrumbs as part of JSON responses:
    return response()->json([
        'data' => $post,
        'breadcrumbs' => Breadcrumbs::generate('post', $post)->toArray(),
    ]);
    

Blade Directives

Extend Blade with custom directives for cleaner syntax:

// app/Providers/BladeServiceProvider.php
Blade::directive('breadcrumbs', function ($expression) {
    return "<?php echo \\Diglactic\\Breadcrumbs\\Breadcrumbs::render($expression); ?>";
});

Usage:

@breadcrumbs('post', $post)

Gotchas and Tips

Pitfalls

  1. Circular Dependencies: Avoid recursive parent() calls without termination conditions:

    // ❌ Bad: Infinite loop
    $trail->parent('category', $category->parent);
    

    Fix: Add a base case (e.g., if (!$category->parent) { $trail->parent('blog'); }).

  2. Missing Route Names: Ensure all routes used in breadcrumbs have names. Anonymous routes won’t work:

    // ❌ Fails
    $trail->push('Home', route('/')); // No name
    

    Fix: Name routes explicitly:

    Route::name('home')->get('/', 'HomeController@index');
    
  3. View Template Overrides: Custom views must match the config key exactly (case-sensitive):

    // ❌ Won't work
    'view' => 'breadcrumbs.custom', // File must be `resources/views/breadcrumbs/custom.blade.php`
    

    Fix: Use dot notation for nested paths:

    'view' => 'partials.breadcrumbs' // File: `resources/views/partials/breadcrumbs.blade.php`
    
  4. Structured Data Conflicts: JSON-LD templates may conflict with URL trimming (e.g., Laravel Page Speed). Exclude breadcrumb routes:

    // config/pagespeed.php
    'exclude' => [
        'breadcrumbs::json-ld',
    ],
    

Debugging

  • Check Registered Trails: Dump all registered breadcrumbs to verify definitions:
    dd(Breadcrumbs::getTrails());
    
  • Inspect Generated Output: Use Breadcrumbs::generate() to debug the raw collection:
    dd(Breadcrumbs::generate('post', $post));
    
  • Clear Cached Views: If templates aren’t updating, clear Blade cache:
    php artisan view:clear
    

Extension Points

  1. Custom Data in Breadcrumbs: Pass additional data to templates via the $data array:

    $trail->push('Post', route('post'), [
        'class' => 'text-primary',
        'aria-label' => 'Featured Post',
    ]);
    

    Access in Blade:

    <li class="{{ $breadcrumb->class ?? '' }}">{{ $breadcrumb->title }}</li>
    
  2. Dynamic View Selection: Override the view at runtime:

    {{ Breadcrumbs::render('post', $post, 'custom.breadcrumbs') }}
    
  3. Event-Based Breadcrumbs: Trigger breadcrumb generation via events (e.g., ModelRetrieved):

    public function handle(ModelRetrieved $event) {
        if ($event->model instanceof Post) {
            Breadcrumbs::for('post', function ($trail, $post) use ($event) {
                $trail->parent('blog');
                $trail->push($post->title, route('posts.show', $post));
            })->with($event->model);
        }
    }
    
  4. Localization: Use Laravel’s translation system for dynamic titles:

    $trail->push(__('breadcrumbs.post'), route('posts.show', $post));
    

    Define translations in resources/lang/en/breadcrumbs.php:

    return [
        'post' => 'Post :title',
    ];
    

Performance Tips

  • Lazy Loading: Defer breadcrumb generation until needed (e.g., in Blade):
    @if (Auth::check())
        {{ Breadcrumbs::render('dashboard') }}
    @endif
    
  • Caching: Cache breadcrumb trails for static routes:
    Breadcrumbs::for('home', function ($trail) {
        $trail->push('Home', route('home'));
    })->cacheFor(60); // Cache for 60 minutes
    
  • Avoid Over-Fetching: Pass only necessary data to breadcrumb closures (e.g., Post::find($id)->title).
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai