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.
composer require diglactic/laravel-breadcrumbs
routes/breadcrumbs.php and define your first breadcrumb trail:
Breadcrumbs::for('home', function ($trail) {
$trail->push('Home', route('home'));
});
{{ Breadcrumbs::render('home') }}
php artisan vendor:publish --tag=breadcrumbs-config
Edit config/breadcrumbs.php to customize the view template.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) }}
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'));
});
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));
});
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));
}
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()) }}
public function handle($request, Closure $next) {
Breadcrumbs::for('dashboard', function ($trail) {
$trail->push('Dashboard', route('dashboard'));
});
return $next($request);
}
boot() for global access:
public function boot() {
Breadcrumbs::for('home', function ($trail) {
$trail->push('Home', route('home'));
});
}
return response()->json([
'data' => $post,
'breadcrumbs' => Breadcrumbs::generate('post', $post)->toArray(),
]);
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)
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'); }).
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');
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`
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',
],
dd(Breadcrumbs::getTrails());
Breadcrumbs::generate() to debug the raw collection:
dd(Breadcrumbs::generate('post', $post));
php artisan view:clear
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>
Dynamic View Selection: Override the view at runtime:
{{ Breadcrumbs::render('post', $post, 'custom.breadcrumbs') }}
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);
}
}
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',
];
@if (Auth::check())
{{ Breadcrumbs::render('dashboard') }}
@endif
Breadcrumbs::for('home', function ($trail) {
$trail->push('Home', route('home'));
})->cacheFor(60); // Cache for 60 minutes
Post::find($id)->title).How can I help you explore Laravel packages today?