Probably one of the most common operation on every website is to assign “active” CSS class to the menu item which is currently opened. There are quite a few ways to detect that status, let’s review them.

We assume that the code will be based on Bootstrap and active menu item will have this:

<li>
    <a href="{{ route('admin.cities.index') }}">
        <i class="fa fa-flag"></i> <span>Countries</span>
    </a>
</li>
<li class="active">
    <a href="{{ route('admin.cities.index') }}">
        <i class="fa fa-bank"></i> <span>Cities</span>
    </a>
</li>
<li>
    <a href="{{ route('admin.cities.index') }}">
        <i class="fa fa-dollar"></i> <span>Currencies</span>
    </a>
</li>

Now, the part that we’re interested in is class=”active”. In real Blade, it should be this:

<li class="{{ ($some_condition_if_active) ? 'active' : '' }}">  

So, how to define that $some_condition_if_active?


Approach 1. Exact URL

Probably, the most simple one – you just check the exact URL and see if it matches:

<li class="{{ (request()->is('admin/cities')) ? 'active' : '' }}">  

We use helper function $request->is().


Approach 2. Starting with the URL

This one is similar, but more flexible – will also match any other URL starting with the one we want, like /admin/cities/create or /admin/cities/1/edit.

We use asterisk (*) symbol for it.

<li class="{{ (request()->is('admin/cities*')) ? 'active' : '' }}">  

Approach 3. Matching URL Segment

Another useful helper is to get URL segments by number.

<li class="{{ (request()->segment(2) == 'cities') ? 'active' : '' }}">  

So, this one will match any URL like /admin/cities, /user/cities/edit etc.


Approach 4. Matching Route by Name

The one that I personally recommend. Route names is a really powerful weapon in case your URLs change for some reason. Let’s say we attached route names with this line in routes/web.php:

Route::middleware(['auth'])->prefix('admin')->name('admin.')->group(function() {
    Route::resource('cities', 'Admin\CityController');
});

So we should match any route name like admin.cities.index or admin.cities.create for menu item to be active.

And here we use Route::getCurrentName() method.

<li class="{{ (strpos(Route::currentRouteName(), 'admin.cities') == 0) ? 'active' : '' }}">  

In this case, all URLs assigned to our resourceful controller will be matched, like /admin/cities, /admin/cities/create, /admin/cities/1/edit etc.