How to Tag a Route in Laravel for Later Use

When building Laravel applications, you might want to categorize routes so they can be retrieved later for specific use cases. One practical example is generating a sitemap.xml
file by filtering only public-facing routes. Laravel does not have a built-in way to tag routes, but we can achieve this using route metadata and custom logic.
Let's see how to achieve that 👇
Approach 1: Adding prefix in route name
Step 1: Defining Routes in routes/web.php
When defining a route in routes/web.php, the simplest approach is using a route name prefix:
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
})->name('public.home');
Route::get('/about', function () {
return view('about');
})->name('public.about');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth')->name('private.dashboard');
Here, we prefix the public routes with public.
to distinguish them.
Step 2: Retrieving Tagged Routes
You can retrieve all registered routes in Laravel using the Route::getRoutes()
method. To filter routes based on their names, you can use:
use Illuminate\Support\Facades\Route;
$publicRoutes = collect(Route::getRoutes())
->filter(function ($route) {
return str_starts_with($route->getName(), 'public.');
})
->map(function ($route) {
return url($route->uri());
});
print_r($publicRoutes->all());
Step 3: Using Tagged Routes in a Sitemap Generator
Now, let's integrate this into a command that generates a sitemap.xml
file:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
class GenerateSitemap extends Command
{
protected $signature = 'sitemap:generate';
protected $description = 'Generate sitemap.xml based on tagged routes';
public function handle()
{
$publicRoutes = collect(Route::getRoutes())
->filter(fn($route) => str_starts_with($route->getName(), 'public.'))
->map(fn($route) => url($route->uri()));
$sitemap = view('sitemap', ['urls' => $publicRoutes]);
Storage::put('sitemap.xml', $sitemap->render());
$this->info('Sitemap generated successfully!');
}
}
Create a sitemap.blade.php
view file that will be used by the command above to render the sitemap.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach($urls as $url)
<url>
<loc>{{ $url }}</loc>
</url>
@endforeach
</urlset>
And that's it. The above command filters out the routes tagged with the prefix public.
, generates an XML view, and saves it.
Now to generate the sitemap run the following command:
php artisan sitemap:generate
Approach 2: Tagging Routes Using Middleware
Another way to tag routes is by using a custom middleware. This allows you to dynamically mark routes without modifying their names.
Step 1: Create a Middleware
Run the following command to create a middleware:
php artisan make:middleware Sitemapped
Step 2: Apply Middleware to Public Routes
use App\Http\Middleware\TagPublicRoutes;
Route::middleware([Sitemapped::class])->group(function () {
Route::get('/', function () {
return view('welcome');
});
Route::get('/about', function () {
return view('about');
});
});
Step 3: Retrieve Tagged Routes in Sitemap Generator
Modify the sitemap command to filter routes based on the middleware tag:
$routes = collect(Route::getRoutes()->getRoutes())->filter(function (\Illuminate\Routing\Route $route) {
if (! in_array('GET', $route->methods)) {
return false;
}
if (! isset($route->action['middleware']) || ! is_array($route->action['middleware'])) {
return false;
}
if (in_array('sitemapped', $route->action['middleware'])) {
return true;
}
return false;
})->map(function ($route) {
return route($route->getName());
})->values()->toArray();
The code above filters out all non-GET urls, and picks the ones that are tagged with the middleware called "sitemapped".
Conclusion
Tagging routes in Laravel using name prefixes or middleware makes it easy to categorize and retrieve them later. Whether for generating a sitemap, creating dynamic navigation, or filtering API endpoints, these approaches are flexible and effective.
Keep building! 🚀