In Laravel, Here’s How to Make a Dynamic Sitemap


A sitemap is an important part of blog management. Its purpose is to make crawling and indexing of our blog content more convenient for search engines. This will, of course, affect the visibility of our material or articles in search engine results. However, this does not rule out the possibility of search engines indexing a site without a sitemap. This is not the case.

Preparing to Make a Sitemap

The url (loc), the last modified date (lastmod), how often it was changed (changefreq), and priority are the most important components to include in a sitemap . The url and the last modified date are the most active of the four elements. Two elements will be made dynamic in this post, while the other two will be made static.

For example, in this discussion, an Eloquent Post Model will be created which contains post_title, post_content, slug, created_at, and updated_at. From this model, the fields that will be used in the sitemap are only slug and updated_at. An example of a migration file that is created is more or less like below.

Schema::create('posts', function (Blueprint $table) {
    $table->string('slug', 200)->unique()->index();

Add the storage configuration in the file config/filesystems.php in section links:

public_path('sitemap') => storage_path('app/sitemap'),

Make a Command Sitemap Generator

The sitemap made in this tutorial is in the form of an xml file that will be updated every 12 p.m. The reason is written as a file so that when the sitemap is crawled by multiple search engine bots at the same time, the server is not overburdened because direct database queries are performed.

The following command can be used to make commands in Laravel:

php artisan make:command SitemapGenerator

Open file Sitemapgenerator.php which is located in app/Console/Commands. Change the following sections:

protected $signature = 'sitemap:generate';

The code above makes a command that can be executed using CMD: php artisan sitemap:generate

protected $description = 'Command to make a sitemap';
public function handle()
    $posts = Post::latest()->limit(5000)->get();
    Storage::put('sitemap/post-sitemap.xml', View::make('sitemap.single-sitemap', ['data' => $posts]));

Making Templates for Sitemaps

Make a folder named sitemap in resources/view. In that folder add a file single-sitemap.blade.php

Add the following code to the sitemap template:

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns:xsi=""
    @foreach ($data as $item)
            <loc>{{url('/')}}/{{ $item->slug }}</loc>
            <lastmod>{{ $item->updated_at->toAtomString() }}</lastmod>

Making a Sitemap Using Command

After completing all of the preceding steps, try to make a sitemap using the command made in the second step. At the root of the Laravel project, run the following command in cmd.

php artisan sitemap:generate

If the code above runs successfully and there is no error notification, it will make a file called post-sitemap.xml in the folder storage/app/sitemap.

Next we need to make a symlink for the sitemap so that it can be accessed using a URL. The trick is simply to run the command below:

php artisan storage:link

After the symlink has been successfully made, then try to access the sitemap via a browser with the address:

Make a Sitemap Automatically

Next is to make a sitemap automatically. The trick is to register the command php artisan sitemap:generate into a cronjob to run periodically as we wish. The method is as follows:

First access SSH then run the command below:

crontab -e

Add the following line of code to the opened cronjob editor

0 0 * * * /usr/local/bin/php /path_laravel/artisan sitemap:generate >> /dev/null 2>&1

Pay attention to the code above there is a section path_laravel which must be replaced according to the laravel project path. The cronjob code above works to run the Sitemap Generator every 12 p.m. every day. So that our sitemap file will always be updated every day.

The last step is to send the sitemap url to the webmaster so that our blog content is indexed immediately.


Please enter your comment!
Please enter your name here