How to Tag a Route in Laravel for Later Use

By Amas
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! 🚀

Share this post.
Liked that? Subscribe to our newsletter for more
Ship fast & don't reinvent the wheel

Build your SaaS using SaaSykit

SaaSykit is a SaaS boilerplate that comes packed with all components required to run a modern SaaS software.

Don't miss this

You might also like