davejamesmiller/laravel-breadcrumbs
Add breadcrumb navigation to Laravel apps with a simple API for defining breadcrumb trails, integrating with your routes and views. Supports named routes, dynamic parameters, and easy rendering so users can see where they are and navigate back.
Installation
composer require davejamesmiller/laravel-breadcrumbs
Publish the config (optional):
php artisan vendor:publish --provider="DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider"
Basic Usage
Register a breadcrumb generator in AppServiceProvider@boot():
use DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs;
use DaveJamesMiller\Breadcrumbs\Generator;
Breadcrumbs::register('home', function (Generator $generator) {
$generator->push('Home', route('home'));
});
First Use Case In a controller or view, generate breadcrumbs for a specific route:
Breadcrumbs::generate('home');
Display in a Blade view:
<div class="breadcrumbs">
{!! Breadcrumbs::render('home') !!}
</div>
config/breadcrumbs.php (default config)app/Providers/AppServiceProvider.php (registration)resources/views/layouts/app.blade.php (common placement)Workflow:
AppServiceProvider@boot():
Breadcrumbs::register('posts.index', function (Generator $generator) {
$generator->parent('home');
$generator->push('Posts', route('posts.index'));
});
Breadcrumbs::generate('posts.index');
Integration Tip: Use middleware to auto-generate breadcrumbs for specific routes:
public function handle($request, Closure $next)
{
Breadcrumbs::generate('posts.show', $request->post);
return $next($request);
}
Pattern: Pass variables to generators
Breadcrumbs::register('posts.show', function (Generator $generator, $post) {
$generator->parent('posts.index');
$generator->push($post->title, route('posts.show', $post));
});
Usage in controller:
Breadcrumbs::generate('posts.show', $post);
Advanced: Use closures for dynamic parent routes:
$generator->parent(function () {
return route('categories.show', $post->category);
});
Basic Rendering:
{!! Breadcrumbs::render() !!}
Custom Templates:
Extend the default template in resources/views/vendor/breadcrumbs/default.blade.php:
<div class="custom-breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
<a href="{{ $breadcrumb->url }}">{{ $breadcrumb->title }}</a>
@endforeach
</div>
Integration with Layouts:
Place in app.blade.php:
@if (Breadcrumbs::has('home'))
<div class="breadcrumbs">
{!! Breadcrumbs::render('home') !!}
</div>
@endif
Unit Test Example:
public function test_breadcrumbs_generation()
{
$this->app->make('DaveJamesMiller\Breadcrumbs\BreadcrumbsGenerator')->generate('home');
$breadcrumbs = Breadcrumbs::get('home');
$this->assertCount(1, $breadcrumbs);
$this->assertEquals('Home', $breadcrumbs->first()->title);
}
Feature Test:
public function test_breadcrumbs_in_view()
{
$this->get('/posts')
->assertSee('Posts');
}
Missing Registration
Call to undefined methodAppServiceProvider@boot() before use.Circular References
->parentIfExists() to avoid errors:
$generator->parentIfExists('home');
Route Caching Issues
php artisan route:clear
Inspect Generated Breadcrumbs Dump the breadcrumb object in a route:
dd(Breadcrumbs::get('home'));
Check for Overrides If breadcrumbs aren’t rendering, verify:
Middleware Conflicts Ensure breadcrumb middleware runs after route resolution:
protected $runAfter = [\Illuminate\Routing\Middleware\SubstituteBindings::class];
Custom Generators Extend the base generator:
class CustomGenerator extends Generator {
public function pushWithIcon($title, $url, $icon) {
$this->items[] = new Breadcrumb($title, $url, ['icon' => $icon]);
}
}
Register in AppServiceProvider:
Breadcrumbs::setGenerator(new CustomGenerator());
Custom Storage Override the default storage (e.g., for multi-tenant apps):
Breadcrumbs::setStorage(new ArrayStorage());
Localization Use Laravel’s localization helpers:
$generator->push(__('Home'), route('home'));
Avoid Over-Generating Only generate breadcrumbs for routes that need them (e.g., skip API routes).
Cache Generators (Advanced) For static breadcrumbs, cache the generator:
if (!Cache::has('breadcrumbs.home')) {
Breadcrumbs::generate('home');
Cache::put('breadcrumbs.home', Breadcrumbs::get('home'), now()->addHours(1));
}
Lazy Loading Defer breadcrumb generation until the view is rendered:
Breadcrumbs::generateIf(function () {
return request()->wantsJson() === false;
}, 'home');
How can I help you explore Laravel packages today?