Creating a Dynamic Sitemap for a Laravel Blog

Creating a Dynamic Sitemap for a Laravel Blog

Published on 11.01.2024

Today, we’re building a dynamic sitemap for our Laravel blog. A sitemap is crucial for SEO, and ensuring it’s always up-to-date can be quite a challenge. But don’t worry, we’ve got a neat solution using a Spatie package.

Getting Started with Spatie

First things first, we need to add the Spatie Laravel Sitemap package to our project. This can be done easily using Composer, the PHP dependency manager. Run the following command in your terminal:

composer require spatie/laravel-sitemap

With Spatie, we’re choosing a more direct approach rather than using a crawler. This leads us to our next step.

Crafting a Sitemap Generator

Let’s create a new action class for our sitemap generator. We initiate a new Sitemap object in this class, as shown below:

class GeneratesSitemapAction {
    public function __invoke () {
        $sitemap = Sitemap::create();
    }
}

Adding Static Pages with Priorities

Our first major step involves collecting all static pages and assigning them priorities. This helps search engines understand the importance of each page. We handle different languages too, making our site more accessible globally. Here’s how we do it:

$languages = [
    'en',
    'de',
];

$routes = [
    'articles.index.get' => 0.9,
    'lighthousecrawler.request.get' => 0.9,
    'pages.data-privacy.get' => 0.1,
    'pages.site-notice.get' => 0.1
];

foreach ($routes as $route => $priority) {
    foreach ($languages as $language) {
        $url = Url::create(route($route, ['language' => $language]))
            ->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)->setPriority($priority);

        foreach ($languages as $alternate_language) {
            $url->addAlternate(route($route, ['language' => $alternate_language]), $alternate_language);
        }

        $sitemap->add($url);
    }
}

Incorporating Article Models

Next, we’re focusing on our article models. Each article gets its own page in the sitemap. We’re also considering the multi-language aspect here, ensuring each page lists alternate languages. This aligns with Google’s recommendations for multi-language sites.

$article_translations = ArticleTranslation::with('article')->whereNotNull('published_at')->get();

foreach ($article_translations as $article_translation) {
    $url = Url::create(route('articles.view.get', [
        'language' => $article_translation->language,
        'slug' => $article_translation->slug,
    ]))->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)->setPriority(0.9);

    foreach ($languages as $alternate_language) {
        $alternate_translation = $article_translation->article->article_translations()->where('language', '=', $alternate_language)->first();

        if (!$alternate_translation) {
            continue;
        }

        $url->addAlternate(route('articles.view.get', [
            'language' => $alternate_language,
            'slug' => $alternate_translation->slug,
        ]), $alternate_language);
    }

    $sitemap->add(
        $url
    );
}

For more details on handling multi-language sites, check out Google’s documentation.

Saving the Sitemap

Finally, we save the sitemap to the public directory. This is crucial for making it accessible to search engines.

$sitemap->writeToFile(\Storage::disk('public')->path('sitemap.xml'));

And that’s it! We’ve successfully created a dynamic, multi-language sitemap for our Laravel blog. This will help search engines better navigate and rank our site, ultimately bringing more visibility and traffic. Happy coding!

Tags:
Laravel
SEO