Laravel: How to Make Menu Item Active by URL/Route
Founder of QuickAdminPanel
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.