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

Active Menu Laravel Package

juy/active-menu

Laravel helper to add an “active” CSS class based on the current route name. Supports exact, wildcard, and multiple route patterns via facade, container, or helper, plus a Blade directive. Configurable active class value.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation:

    composer require juy/active-menu
    
  2. Register Service Provider: Add Juy\ActiveMenu\ServiceProvider::class to config/app.php under providers.

  3. Publish Config (optional):

    php artisan vendor:publish --provider="Juy\ActiveMenu\ServiceProvider" --tag="config"
    

    (Default config is fine unless you need to customize the active class.)

  4. First Use Case: In a Blade template, check if the current route matches a name (e.g., dashboard) and apply the active class:

    <li class="{{ Active::route('dashboard') ? 'active' : '' }}">
        <a href="{{ route('dashboard') }}">Dashboard</a>
    </li>
    

Implementation Patterns

Core Workflows

  1. Route-Based Active State: Use Active::route('route.name') to conditionally apply classes to navigation items:

    <li class="{{ Active::route(['dashboard', 'settings.index']) ? 'active' : '' }}">
        <a href="{{ route('dashboard') }}">Dashboard</a>
    </li>
    

    (Supports arrays for multiple route names.)

  2. Dynamic Navigation Menus: Loop through menu items and check each route dynamically:

    $menuItems = [
        ['name' => 'Dashboard', 'route' => 'dashboard'],
        ['name' => 'Profile', 'route' => 'profile.edit'],
    ];
    
    @foreach($menuItems as $item)
        <li class="{{ Active::route($item['route']) ? 'active' : '' }}">
            <a href="{{ route($item['route']) }}">{{ $item['name'] }}</a>
        </li>
    @endforeach
    
  3. Partial Matches (Prefixes): Use Active::prefix('admin.') to highlight routes under a prefix:

    <li class="{{ Active::prefix('admin.') ? 'active' : '' }}">
        Admin Panel
    </li>
    
  4. Facade vs. Helper: Prefer the Active facade for readability in Blade:

    {{ Active::route('home') ? 'text-blue-500' : '' }}
    

    (Avoid direct class instantiation unless extending functionality.)


Integration Tips

  1. Blade Directives: Create a custom directive for cleaner syntax:

    // In a service provider
    Blade::directive('active', function ($expression) {
        return "<?php echo \\Active::route({$expression}) ? 'active' : ''; ?>";
    });
    

    Usage:

    <li class="@active('dashboard')">...</li>
    
  2. View Composers: Pass active state logic to views via composers:

    public function compose($view) {
        $view->with('isDashboard', Active::route('dashboard'));
    }
    
  3. JavaScript Integration: Use the active state to trigger JS logic (e.g., tab switching):

    if (document.querySelector('.active').dataset.route === 'settings') {
        loadSettingsTab();
    }
    
  4. Multi-Level Menus: Combine with nested Blade loops for hierarchical menus:

    @if(Active::prefix('admin.'))
        <ul class="submenu">
            @foreach($adminRoutes as $route)
                <li class="{{ Active::route($route) ? 'active' : '' }}">
                    <a href="{{ route($route) }}">{{ $route }}</a>
                </li>
            @endforeach
        </ul>
    @endif
    

Gotchas and Tips

Pitfalls

  1. Route Caching:

    • If using route caching (php artisan route:cache), clear it after adding new routes to avoid stale active states.
    • Test with php artisan route:clear in development.
  2. Case Sensitivity:

    • Route names are case-sensitive. Ensure consistency (e.g., dashboard vs. Dashboard).
  3. Middleware Interference:

    • Routes behind middleware (e.g., auth) may not trigger active states if the user isn’t authenticated. Test edge cases.
  4. Dynamic Routes:

    • Named routes with parameters (e.g., posts.show, {post}) won’t match unless the exact name is provided. Use Active::route('posts.show', $post->id) if needed (requires custom logic).
  5. Facade Availability:

    • The Active facade is only available after the service provider is registered. Avoid using it in AppServiceProvider boot methods.

Debugging

  1. Check Current Route: Dump the current route name for debugging:

    dd(Route::current()->getName());
    
  2. Verify Config: Ensure config/activemenu.php hasn’t been overridden with an empty class value.

  3. Test with Hardcoded Values: Temporarily hardcode the active class to isolate issues:

    <li class="{{ 'active' }}">...</li>
    

    (If the style applies, the issue is with Active::route() logic.)


Extension Points

  1. Custom Matching Logic: Extend the package by creating a decorator:

    class CustomActive extends \Juy\ActiveMenu\Active {
        public function isCurrent($routes) {
            // Add custom logic (e.g., check URL segments)
            return parent::isCurrent($routes) || str_contains(request()->path(), 'custom-path');
        }
    }
    

    Bind it in a service provider:

    $this->app->bind('Active', function () {
        return new CustomActive();
    });
    
  2. Multiple Active Classes: Modify the config to support multiple classes:

    'classes' => [
        'active' => 'default-active',
        'nested' => 'nested-active',
    ],
    

    (Requires updating the package source or creating a wrapper.)

  3. Laravel 8+ Compatibility: Override the service provider to support newer Laravel versions:

    public function register() {
        if (! $this->app->has('Active')) {
            $this->app->singleton('Active', function () {
                return new \Juy\ActiveMenu\Active();
            });
        }
    }
    
  4. Vue/React Integration: Pass active state via API or props:

    // Vue example
    data() {
        return {
            isActive: {!! json_encode(Active::route('dashboard')) !!}
        };
    }
    

Pro Tips

  • Performance: The package is lightweight; no need to optimize further unless profiling shows bottlenecks.
  • Testing: Use Route::current() in PHPUnit to mock active states:
    Route::current(function () {
        return Route::getRoutes()->getByName('dashboard');
    });
    
  • Dark Mode: Combine with Tailwind’s dark variants:
    <li class="{{ Active::route('dashboard') ? 'text-blue-500 dark:text-blue-400' : '' }}">
    
  • Localization: Use the active state to switch languages:
    @if(Active::route('dashboard'))
        <button onclick="changeLanguage('en')">English</button>
    @endif
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle