# Laravel Breadcrumbs
Laravel Breadcrumbs is a package that provides a simple, Laravel-style way to create breadcrumb navigation trails in your web application. It allows you to define breadcrumbs for each page using closures that can accept parameters, making it easy to build dynamic breadcrumb trails that reflect your application's navigation hierarchy. The package follows Laravel conventions and integrates seamlessly with Laravel's routing system.
The package supports route model binding, parent-child breadcrumb relationships, custom templates for different CSS frameworks (Bootstrap, Tailwind, Bulma, etc.), and JSON-LD structured data for SEO. It provides a fluent API through the `Breadcrumbs` facade with methods to define, generate, and render breadcrumbs, along with advanced features like before/after callbacks, custom data injection, and runtime view switching.
## API Reference
### Breadcrumbs::for() - Define Breadcrumbs for a Page
Registers a breadcrumb-generating callback for a specific page. The callback receives a `BreadcrumbTrail` instance and optional parameters.
```php
push('Home', route('home'));
});
// Breadcrumb with parent
Breadcrumbs::for('blog', function (BreadcrumbTrail $trail) {
$trail->parent('home');
$trail->push('Blog', route('blog'));
});
// Dynamic breadcrumb with parameter
Breadcrumbs::for('post', function (BreadcrumbTrail $trail, Post $post) {
$trail->parent('blog');
$trail->push($post->title, route('post', $post));
});
// Arrow function syntax (PHP 7.4+)
Breadcrumbs::for(
'category',
fn (BreadcrumbTrail $trail, $category) => $trail
->parent('blog')
->push($category->title, route('category', $category))
);
```
### Breadcrumbs::render() - Display Breadcrumbs in Views
Renders breadcrumbs using the configured template (default: Bootstrap 5). Accepts breadcrumb name and optional parameters.
```blade
{{-- Basic usage in Blade template --}}
{{ Breadcrumbs::render('home') }}
{{-- With parameter --}}
{{ Breadcrumbs::render('post', $post) }}
{{-- With multiple parameters --}}
{{ Breadcrumbs::render('comment', $post, $comment) }}
{{-- Route-bound breadcrumbs (auto-detect current route) --}}
{{ Breadcrumbs::render() }}
{{-- Output example (Bootstrap 5):
--}}
```
### Breadcrumbs::generate() - Get Breadcrumb Collection
Generates breadcrumbs and returns them as a Collection without rendering, useful for custom processing or manual rendering.
```php
url) && !$loop->last)
{{ $breadcrumb->title }}
@else
{{ $breadcrumb->title }}
@endif
@if (!$loop->last) / @endif
@endforeach
// Use Collection methods
$breadcrumbs = Breadcrumbs::generate('post', $post);
$count = $breadcrumbs->count(); // 3
$first = $breadcrumbs->first(); // {title: "Home", url: "/"}
$filtered = $breadcrumbs->filter(fn($b) => $b->url !== null);
```
### $trail->push() - Add Breadcrumb to Trail
Adds a single breadcrumb to the trail with title, optional URL, and optional custom data.
```php
push('Home', route('home'));
// Without URL (no link)
$trail->push('Current Page');
// With custom data for templates
$trail->push('Dashboard', route('dashboard'), ['icon' => 'dashboard.svg']);
// With custom data for structured data
$trail->push('Product', route('product', $product), [
'image' => asset('products/' . $product->image)
]);
});
// Access custom data in custom template
@foreach ($breadcrumbs as $breadcrumb)
@endforeach
```
### $trail->parent() - Add Parent Breadcrumbs
Links to a parent breadcrumb definition, automatically including all ancestors in the trail.
```php
parent('home');
$trail->push('Products', route('products.index'));
});
// Child with static parent
Breadcrumbs::for('product.show', function (BreadcrumbTrail $trail, $product) {
$trail->parent('products');
$trail->push($product->name, route('product.show', $product));
});
// Recursive parent for nested categories
Breadcrumbs::for('category', function (BreadcrumbTrail $trail, Category $category) {
if ($category->parent) {
$trail->parent('category', $category->parent);
} else {
$trail->parent('products');
}
$trail->push($category->name, route('category', $category));
});
// Result: Home / Products / Electronics / Phones / iPhone
```
### Breadcrumbs::view() - Render with Custom View
Renders breadcrumbs using a specified view template instead of the default configured view.
```php
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'product', $product) }}
{{ Breadcrumbs::view('breadcrumbs::bootstrap5', 'product', $product) }}
{{-- Built-in views: bootstrap4, bootstrap5, bulma, foundation6,
json-ld, materialize, tailwind, uikit --}}
```
### Breadcrumbs::before() and Breadcrumbs::after() - Register Callbacks
Registers callbacks that run before or after breadcrumb generation, useful for automatically adding common breadcrumbs.
```php
push('Home', route('home'));
});
// Add pagination to end of trail
Breadcrumbs::after(function (BreadcrumbTrail $trail) {
$page = (int) request('page', 1);
if ($page > 1) {
$trail->push("Page {$page}");
}
});
// Add current user context
Breadcrumbs::before(function (BreadcrumbTrail $trail) {
if (auth()->check() && request()->is('admin/*')) {
$trail->push('Admin Panel', route('admin.dashboard'));
}
});
// Exclude pagination from current page detection
Breadcrumbs::after(function (BreadcrumbTrail $trail) {
$page = (int) request('page', 1);
if ($page > 1) {
$trail->push("Page {$page}", null, ['current' => false]);
}
});
```
### Breadcrumbs::current() - Get Current Page Breadcrumb
Returns the last breadcrumb in the trail, typically representing the current page.
```php
title : 'Default Title';
$url = $current ? $current->url : null;
```
```blade
{{-- Use in page title --}}
{{ ($breadcrumb = Breadcrumbs::current()) ? $breadcrumb->title : 'Default' }}
- My App
{{-- Use in heading --}}
{{ Breadcrumbs::current()?->title ?? 'Welcome' }}
{{-- Advanced filtering with Collection methods --}}
where('current', '!==', false)
->last();
?>
```
### Breadcrumbs::exists() - Check if Breadcrumb Exists
Checks whether a breadcrumb with the given name has been registered.
```php
No breadcrumb trail available';
}
// Conditional rendering in controller
public function show(Post $post)
{
$hasBreadcrumbs = Breadcrumbs::exists('post');
return view('post.show', compact('post', 'hasBreadcrumbs'));
}
```
### Route-Bound Breadcrumbs - Automatic Route Detection
Automatically renders breadcrumbs based on the current route name when no parameters are passed to render().
```php
get('/', 'HomeController@index');
Route::name('posts.index')->get('/posts', 'PostController@index');
Route::name('posts.show')->get('/posts/{post}', 'PostController@show');
// routes/breadcrumbs.php
use Diglactic\Breadcrumbs\Breadcrumbs;
use Diglactic\Breadcrumbs\Generator as BreadcrumbTrail;
use App\Models\Post;
Breadcrumbs::for('home', function (BreadcrumbTrail $trail) {
$trail->push('Home', route('home'));
});
Breadcrumbs::for('posts.index', function (BreadcrumbTrail $trail) {
$trail->parent('home');
$trail->push('Posts', route('posts.index'));
});
Breadcrumbs::for('posts.show', function (BreadcrumbTrail $trail, Post $post) {
$trail->parent('posts.index');
$trail->push($post->title, route('posts.show', $post));
});
// Custom 404 page
Breadcrumbs::for('errors.404', function (BreadcrumbTrail $trail) {
$trail->parent('home');
$trail->push('Page Not Found');
});
```
```blade
{{-- resources/views/layouts/app.blade.php --}}
```
### Breadcrumbs::macro() - Extend with Custom Methods
Adds custom methods to the Breadcrumbs facade using Laravel's macroable trait.
```php
title} – " : '';
if (($page = (int) request('page')) > 1) {
$title .= "Page $page – ";
}
return $title . config('app.name');
});
// Define resource breadcrumbs macro
Breadcrumbs::macro('resource', function (string $name, string $title) {
Breadcrumbs::for("{$name}.index", function ($trail) use ($name, $title) {
$trail->parent('home');
$trail->push($title, route("{$name}.index"));
});
Breadcrumbs::for("{$name}.create", function ($trail) use ($name) {
$trail->parent("{$name}.index");
$trail->push('New', route("{$name}.create"));
});
Breadcrumbs::for("{$name}.show", function ($trail, $model) use ($name) {
$trail->parent("{$name}.index");
$trail->push($model->title, route("{$name}.show", $model));
});
});
// Use the macros
Breadcrumbs::resource('posts', 'Blog Posts');
Breadcrumbs::resource('users', 'Users');
```
```blade
{{ Breadcrumbs::pageTitle() }}
```
### Configuration - Customize Package Behavior
Configure breadcrumb file locations, views, exception handling, and custom classes.
```bash
# Publish configuration file
php artisan vendor:publish --tag=breadcrumbs-config
# Publish view templates for customization
php artisan vendor:publish --tag=breadcrumbs-views
```
```php
'breadcrumbs::bootstrap5',
// Breadcrumb definition files
'files' => base_path('routes/breadcrumbs.php'),
// Multiple files
'files' => [
base_path('breadcrumbs/admin.php'),
base_path('breadcrumbs/frontend.php'),
],
// Wildcard loading
'files' => glob(base_path('breadcrumbs/*.php')),
// Exception handling
'unnamed-route-exception' => true,
'missing-route-bound-breadcrumb-exception' => true,
'invalid-named-breadcrumb-exception' => true,
// Custom classes for advanced customization
'manager-class' => Diglactic\Breadcrumbs\Manager::class,
'generator-class' => Diglactic\Breadcrumbs\Generator::class,
];
```
### JSON-LD Structured Data - SEO-Friendly Breadcrumbs
Renders breadcrumbs as JSON-LD structured data for search engine optimization.
```blade
{{-- resources/views/products/show.blade.php --}}
{{ $product->name }}
{{-- JSON-LD structured data for SEO --}}
{{ Breadcrumbs::view('breadcrumbs::json-ld', 'product.show', $product) }}
{{-- Visible breadcrumb navigation --}}
{{ Breadcrumbs::render('product.show', $product) }}
{{ $product->name }}
{{-- Output in :
--}}
```
```php
parent('products.index');
$trail->push(
$product->name,
route('product.show', $product),
['image' => asset('products/' . $product->image)]
);
});
```
### Custom Template - Create Your Own Breadcrumb View
Create custom breadcrumb templates with full control over HTML output and styling.
```blade
{{-- resources/views/partials/breadcrumbs.blade.php --}}
@unless ($breadcrumbs->isEmpty())
@endunless
{{-- Available variables:
$breadcrumbs - Collection of breadcrumb objects
$breadcrumb->title - The breadcrumb title
$breadcrumb->url - The breadcrumb URL (or null)
$breadcrumb->{custom} - Any custom data passed via push()
--}}
```
```php
'partials.breadcrumbs',
];
```
## Summary
Laravel Breadcrumbs is designed for Laravel applications that need hierarchical navigation trails. Common use cases include e-commerce sites with category hierarchies, blog platforms with post categorization, admin panels with multi-level sections, documentation sites, and any application with nested page structures. The package excels at building dynamic breadcrumbs that respond to route parameters and model relationships, making it ideal for applications with complex navigation patterns.
Integration is straightforward: install via Composer, define breadcrumbs in `routes/breadcrumbs.php` using the fluent API, and render them in Blade templates with a single method call. The package integrates with Laravel's routing system through route-bound breadcrumbs, supports all major CSS frameworks out of the box, and provides JSON-LD structured data for SEO. Advanced features include before/after callbacks for common breadcrumb patterns, custom data injection for template flexibility, macro support for extending functionality, and full customization through subclassing core classes.