Building a Dynamic XML Sitemap in Laravel: A Step-by-Step Guide

Learn how to create a dynamic XML sitemap in Laravel from a list of links. Step-by-step guide with controller, Blade template, and route setup for your web app.

If you’ve ever wondered how search engines like Google actually find and index your Laravel-powered website, the answer often lies in a well-structured XML sitemap. Without one, even your best content might stay hidden in the shadows. The good news? Generating a dynamic XML sitemap in Laravel is easier than you think.

In this guide, I’ll walk you through a step-by-step process to build a dynamic XML sitemap in Laravel from any list of links—helping your site become more SEO-friendly and crawlable in just minutes.

Step 1: Create a Controller

We’ll start by creating a SitemapController to generate the XML response.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Response;

class SitemapController extends Controller
{
    public function index()
    {
        // Example list of links (this can come from DB or config)
        $links = [
            ['url' => url('/'), 'updated_at' => now()],
            ['url' => url('/about'), 'updated_at' => now()->subDays(2)],
            ['url' => url('/contact'), 'updated_at' => now()->subDays(5)],
        ];

        $content = view('sitemap', compact('links'));

        return response($content, 200)
            ->header('Content-Type', 'application/xml');
    }
}

You can extend this controller to fetche links from your database (e.g., posts, products, categories) automatically instead of a manual list like below:

<?php

namespace App\Http\Controllers;

use App\Models\Page;
use Illuminate\Http\Response;

class SitemapController extends Controller
{
    public function index()
    {
        // Example list of links (this can come from DB or config)
        $links = Page::all();

        $content = view('sitemap', compact('links'));

        return response($content, 200)
            ->header('Content-Type', 'application/xml');
    }
}

Alternative Solution

If you don’t want to create controller, you can add this code directly to routes/web.php route as follows:

<?php

use App\Models\Page;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

Route::get('/sitemap.xml', function () {
    $links = Page::all();

    $content = view('sitemap', [
        'links' => $links,
    ]);

    return response($content, 200)
            ->header('Content-Type', 'application/xml');
});

Step 2: Create the Blade View

Create a new file at resources/views/sitemap.blade.php and paste the following code:

{!! '<?xml version="1.0" encoding="UTF-8"?>' !!}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach ($links as $link)
        <url>
            <loc>{{ $link->url }}</loc>
            <lastmod>{{ \Carbon\Carbon::parse($link->updated_at)->toAtomString() }}</lastmod>
            <changefreq>weekly</changefreq>
            <priority>0.8</priority>
        </url>
    @endforeach
</urlset>

Note: We use {!! '<?xml version="1.0" encoding="UTF-8"?>' !!} because Blade treats <?xml ... ?> as a PHP tag, which causes a syntax error.


Step 3: Add the Route

Open routes/web.php and add:

use App\Http\Controllers\SitemapController;

Route::get('/sitemap.xml', [SitemapController::class, 'index']);

Note: If you have directly added the code of sitemap to this file, then you can skip this step.


Step 4: Test Your Sitemap

Now, visit:

https://yourapp.com/sitemap.xml

You should see a valid sitemap like this:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://yourapp.com/</loc>
        <lastmod>2025-09-17T09:10:00+00:00</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>https://yourapp.com/about</loc>
        <lastmod>2025-09-15T09:10:00+00:00</lastmod>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
    </url>
</urlset>

Conclusion

With just a few steps, you’ve created a dynamic XML sitemap in Laravel. You can extend this by fetching links from your database (e.g., blog posts, products, categories) instead of a static list.

This setup ensures your site is search engine friendly and keeps your content crawlable and indexable.