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 Navigation Laravel Package

spatie/laravel-navigation

Define a navigation tree for Laravel apps and reuse it to build menus, breadcrumbs, and other nav UI. Manage sections, nested items, and active state in PHP, register navigation via service providers/container events, and render however you like.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-navigation
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Spatie\Navigation\NavigationServiceProvider"
    
  2. First Use Case: Define a navigation tree in a service provider or controller:

    use Spatie\Navigation\Navigation;
    use Spatie\Navigation\Section;
    
    Navigation::make('main', function () {
        return [
            Section::make('Home', route('home'))
                ->activeWhen(fn () => request()->is('home')),
            Section::make('Blog', route('blog.index'))
                ->activeWhen(fn () => request()->is('blog/*')),
        ];
    });
    
  3. Accessing Navigation: In a Blade view:

    @foreach (Navigation::get('main') as $section)
        <a href="{{ $section->url }}" class="{{ $section->isActive() ? 'active' : '' }}">
            {{ $section->title }}
        </a>
    @endforeach
    

Implementation Patterns

Core Workflows

  1. Dynamic Navigation Trees: Use closures to define navigation dynamically (e.g., based on user roles or permissions):

    Navigation::make('admin', function () {
        return auth()->user()->can('access-admin')
            ? [
                Section::make('Dashboard', route('admin.dashboard')),
                Section::make('Users', route('admin.users.index')),
            ]
            : [];
    });
    
  2. Nested Sections: Build hierarchical navigation (e.g., dropdowns):

    Navigation::make('sidebar', function () {
        return [
            Section::make('Products')
                ->addChildren([
                    Section::make('All Products', route('products.index')),
                    Section::make('Categories', route('products.categories')),
                ]),
        ];
    });
    
  3. Active State Logic: Customize active state checks with closures or methods:

    Section::make('Profile', route('profile.show'))
        ->activeWhen(fn () => request()->routeIs('profile.*'));
    
  4. Breadcrumbs: Define breadcrumbs separately and reuse sections:

    Navigation::make('breadcrumbs', function () {
        return [
            Section::make('Home', route('home')),
            Section::make('Blog', route('blog.index')),
            Section::make('Post', route('blog.post', ['post' => 1])),
        ];
    });
    

Integration Tips

  • Blade Components: Create reusable components for rendering navigation:

    <x-navigation.render :sections="Navigation::get('main')" />
    
    // In a Blade component
    public function render()
    {
        return view('components.navigation', [
            'sections' => $this->sections,
        ]);
    }
    
  • JavaScript Frameworks: Pass navigation data to Vue/React via Laravel Mix or Inertia.js:

    // Inertia.js example
    const navigation = @json(Navigation::get('main'));
    
  • API Responses: Expose navigation structure in API responses:

    return response()->json([
        'navigation' => Navigation::get('main')->toArray(),
    ]);
    

Gotchas and Tips

Pitfalls

  1. Caching Navigation: Navigation is cached by default (TTL: 1 hour). Clear cache when dynamically updating navigation:

    php artisan cache:clear
    

    Or disable caching in config/navigation.php:

    'cache' => false,
    
  2. Active State Conflicts: Ensure activeWhen closures are mutually exclusive to avoid multiple sections appearing active.

  3. Nested Section URLs: Child sections inherit the parent’s URL unless explicitly overridden. Test nested routes carefully.

  4. Dependency Injection: Avoid instantiating Navigation directly in controllers. Use dependency injection or the Navigation facade.

Debugging

  • Dump Navigation Structure:
    dd(Navigation::get('main')->toArray());
    
  • Check Cache: Verify cached navigation isn’t stale:
    Navigation::clearCache();
    

Extension Points

  1. Custom Section Classes: Extend Spatie\Navigation\Section to add metadata:

    class CustomSection extends Section
    {
        public function hasPermission(): bool
        {
            return auth()->user()->can($this->permission);
        }
    }
    
  2. Middleware for Navigation: Dynamically modify navigation in middleware:

    public function handle(Request $request, Closure $next)
    {
        Navigation::extend('main', function () {
            return auth()->check() ? [...] : [];
        });
        return $next($request);
    }
    
  3. Localization: Use Laravel’s localization helpers for multilingual navigation:

    Section::make(__('Home'), route('home'))
        ->locale('en')
        ->activeWhen(fn () => app()->getLocale() === 'en');
    
  4. Testing: Mock navigation in tests:

    Navigation::fake([
        'main' => [
            Section::make('Test', '#'),
        ],
    ]);
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport