Date
3 min read

Simple breadcrumbs in Laravel

Table of contents:

Usage:

This simple tutorial demonstrates how we can elegantly define breadcrumbs through the backend through controllers, middleware and/or service providers.

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    app('breadcrumbs')->push([
        Breadcrumb::make(
            'Posts',
            route('posts.index'),
        ),
        Breadcrumb::make('Create'),
    ]);

    // ...
}

Additionally, you could use a middleware or a service provider to define an initial breadcrumb, such as the ‘Dashboard’ or ‘Home’.

Service Providers as we know boot first. There is then an initial check to see whether the current route is the dashboard if so then it does not need to be clickable, else then it will link to the dashboard.

<?php

namespace App\Providers;

use App\Breadcrumb;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->booted(function () {
            app('breadcrumbs')->add(
                Breadcrumb::make(
                    'Dashboard',
                    Route::getCurrentRoute()->getName()
                      ? route('admin.index')
                      : null
                )
            );
        });
    }
}

Setup:

First let’s create create a new custom collection class and register that within a service provider as a singleton.

As we know, singletons will always return the same instance, getting resolved out of the container and therefore we can push to the collection in real time.

<?php

namespace App\Collections;

use Illuminate\Support\Collection;

class Breadcrumbs extends Collection
{
    // ...
}
<?php

namespace App\Providers;

use App\Collections\Breadcrumbs;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('breadcrumbs', function () {
            return new Breadcrumbs;
        });
    }
}

Next, we should build up a breadcrumb class, this is used to push to the breadcrumbs each time we need to define a new one.

My personal preference is to use Spatie’s Data Transfer Object repository. This class accepts a title, path and icon string.

<?php

namespace App;

use Spatie\DataTransferObject\DataTransferObject;

class Breadcrumb extends DataTransferObject
{
    public string $title;

    public string $path = '';

    public string $icon = '';

    /**
     * Construct a new instance of the class.
     *
     * @return static
     */
    public static function make(string $title, string $path = '')
    {
        return new static(compact('title', 'path'));
    }

    /**
     * Specify the path.
     *
     * @return $this
     */
    public function path(string $path = '')
    {
        $this->path = $path;

        return $this;
    }

    /**
     * Specify the icon.
     *
     * @return $this
     */
    public function icon(string $icon = '')
    {
        $this->icon = $icon;

        return $this;
    }
}

Present:

Lastly, the below is a simple demonstration of presenting those breadcrumbs. This uses TailwindCSS and Blade UI Kit - Blade Icons

@if (app('breadcrumbs')->isNotEmpty())
    <nav class="flex p-4 lg:px-8 border-t border-t-slate-100" aria-label="Breadcrumb">
        <ol class="inline-flex items-center gap-x-2">
            @foreach (app('breadcrumbs') as $breadcrumb)
                <li class="inline-flex items-center">
                    @if (($breadcrumb->path ?? '') && !$loop->last)
                        <a href="{{ $breadcrumb->path }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 underline">
                            @if($breadcrumb->icon ?? '')
                                @svg($breadcrumb->icon, 'w-6 h-6')
                            @endif

                            <span @class([
                                'ml-3' => $breadcrumb->icon ?? '',
                            ])>{{ $breadcrumb->title }}</span>

                            @svg('heroicon-o-chevron-right', 'w-3 h-3 ml-2')
                        </a>
                    @else
                        <div class="inline-flex items-center text-sm font-medium text-gray-700">
                            @if($breadcrumb->icon ?? '')
                                @svg($breadcrumb->icon, 'w-6 h-6')
                            @endif

                            <span @class([
                                'ml-3' => $breadcrumb->icon ?? '',
                            ])>{{ $breadcrumb->title }}</span>
                        </div>
                    @endif
                </li>
            @endforeach
        </ol>
    </nav>
@endif

You might also like...

  • Read article

    Generating and Enforcing UUIDs in Laravel for Immutable Model IDs

    Ensure models always have a UUID set.

  • Read article

    Laravel update multiple rows with different values

    Discover efficient techniques for updating multiple rows with unique values in Laravel. Explore step-by-step instructions and practical examples to streamline your database operations.

  • Read article

    Exporting large amounts of data in Laravel

    An opinionated approach on how best to handle exporting large amounts of data in Laravel using commands and queues.

Let's work together 🤝

Line
Christopher Kelker

Chriscreates