How to Automatically Generate an XML Sitemap in Laravel

How to Automatically Generate an XML Sitemap in Laravel
Share this:

How often should I update my sitemap? What should I include in it? Should I create a new sitemap every time. I add or remove a page from my site?

The sitemap is a file that contains links to all pages on your site. This helps search engines crawl your site better and index your pages faster.

Sitemaps are essential for SEO (search engine optimization). They allow search engines to crawl your entire site and index its contents.

We are going to create a XML Sitemap for our posts using a spatie/laravel-sitemap package.

Follow the below Step-by-Step Guide on how to automatically generate an XML Sitemap in Laravel Application.

Load WordPress Sites in as fast as 37ms!

How to Automatically Generate an XML Sitemap in Laravel

  • Step 1: Install Laravel Application
  • Step 2: Create Database and Configure
  • Step 3: Installing spatie/laravel-sitemap Package
  • Step 4: Creating Post Model, Migration and Controller
  • Step 5: Create Dummy Records for Post
  • Step 6: Create Sitemap Command
  • Step 7: Scheduled Command in Console Kernel
  • Step 8: Testing

Step 1: Install Laravel Application

Firstly, we will install a laravel application. To install a laravel application run the following code in terminal as show in figure.

composer create-project --prefer-dist laravel/laravel laravel-sitemap
cd laravel-sitemap
Install Laravel Application
Install Laravel Application

Step 2: Create Database and Configure

Let create database in phpmyadmin for our project for adding posts and then we will create those posts sitemap later.

We are creating a database with name “laravel-sitemap” as you can see in below image.

Creating Database in PhpMyAdmin
Creating Database in PhpMyAdmin

After creating database we are going to configure it to our laravel application. To configure the database in laravel. First open .env from our project root directory and enter the database details as show below.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-sitemap
DB_USERNAME=root
DB_PASSWORD=
Database Configuration in Laravel Application
Database Configuration in Laravel Application

Now run the migration to create a default tables like users table etc.

php artisan migrate
Database Migration
Database Migration

Step 3: Installing spatie/laravel-sitemap Package

We are using spatie/laravel-sitemap package to generate our posts sitemap. We are going to install the package via composer using a following command in terminal.

composer require spatie/laravel-sitemap
Installing spatie/laravel-sitemap Package
Installing spatie/laravel-sitemap Package

The package will automatically register itself.

Configuration Package

You can override the default options for the crawler. First publish the configuration:

php artisan vendor:publish --provider="Spatie\Sitemap\SitemapServiceProvider" --tag=sitemap-config

This will copy the default config to config/sitemap.php where you can edit it.

use GuzzleHttp\RequestOptions;
use Spatie\Sitemap\Crawler\Profile;

return [

    /*
     * These options will be passed to GuzzleHttp\Client when it is created.
     * For in-depth information on all options see the Guzzle docs:
     *
     * http://docs.guzzlephp.org/en/stable/request-options.html
     */
    'guzzle_options' => [

        /*
         * Whether or not cookies are used in a request.
         */
        RequestOptions::COOKIES => true,

        /*
         * The number of seconds to wait while trying to connect to a server.
         * Use 0 to wait indefinitely.
         */
        RequestOptions::CONNECT_TIMEOUT => 10,

        /*
         * The timeout of the request in seconds. Use 0 to wait indefinitely.
         */
        RequestOptions::TIMEOUT => 10,

        /*
         * Describes the redirect behavior of a request.
         */
        RequestOptions::ALLOW_REDIRECTS => false,
    ],
    
    /*
     * The sitemap generator can execute JavaScript on each page so it will
     * discover links that are generated by your JS scripts. This feature
     * is powered by headless Chrome.
     */
    'execute_javascript' => false,
    
    /*
     * The package will make an educated guess as to where Google Chrome is installed. 
     * You can also manually pass it's location here.
     */
    'chrome_binary_path' => '',

    /*
     * The sitemap generator uses a CrawlProfile implementation to determine
     * which urls should be crawled for the sitemap.
     */
    'crawl_profile' => Profile::class,
    
];

Step 4: Creating Post Model, Migration and Controller

We are going to create posts XML sitemaps. So we are going to create post model, migration and controller for it.

By running the following command its will create all three model migration and model for post.

php artisan make:model Post -mc

-mc will create a migraion and controller.

Creating Post Model, Migration and Controller
Creating Post Model, Migration and Controller

Now we are going to update it.

app/Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 
        'slug', 
        'description'
    ];
}
Update Post Model
Update Post Model

database/migrations/create_posts_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug');
            $table->text('description'); 
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
};
Update Post Migrations
Update Post Migrations

We don’t need to update PostController.php file for this tutorial because we are going to add dummy records for posts using faker in our next step.

If you want to add, edit, update or to display posts you can using PostController.php. You can check out our article Laravel 9 Vue JS CRUD App using Vite Example. We had discuss the CRUD in deatils.

Run the migration to create our new post table.

php artisan migrate

Step 5: Create Dummy Records for Post

Now we are going to add some dummy records to the post table so that we can generate a XML sitemap for posts.

You can skip this part if you already create a post.

So, now we are going to create factory for our post model using the following command.

php artisan make:factory PostFactory --model=Post
Creating Post Factory
Creating Post Factory

Update the database/factories/PostFactory.php file.

<?php

namespace Database\Factories;
use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
 */
class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'title' => $this->faker->sentence($nbWords = 6, $variableNbWords = true),
            'slug' => $this->faker->randomNumber($nbDigits = NULL, $strict = false),
            'description' => $this->faker->text($maxNbChars = 2000)
        ];
    }
}
Updating Post Factory
Updating Post Factory

Note for slug we are using some random numbers.

Now we are going to generate some random post using tinker.

php artisan tinker
Post::factory()->count(30)->create()

30 is the total number of post we want to generate.

Generate Posts Using Tinker
Generate Posts Using Tinker

Now you can Exit from tinker using exit command.

exit

Step 6: Creating Sitemap Command

You can easily create an artisan command to create a sitemap and schedule it to run frequently. This will ensure that new pages and content types will be automatically picked up. To create a sitemap command run the following command.

php artisan make:command GenerateSitemap
Create Sitemap Command
Create Sitemap Command

Update the sitemap command with the following code.

app/Console/Commands/GenerateSitemap.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;

use App\Models\Post;

class GenerateSitemap extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'sitemap:generate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Automatically Generate an XML Sitemap';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $postsitmap = Sitemap::create();

        Post::get()->each(function (Post $post) use ($postsitmap) {
            $postsitmap->add(
                Url::create("/post/{$post->slug}")
                    ->setPriority(0.9)
                    ->setChangeFrequency(Url::CHANGE_FREQUENCY_MONTHLY)
            );
        });

        $postsitmap->writeToFile(public_path('sitemap.xml'));
    }
}
  • sitemap:generate is our command to generate the sitemap.
  • “setPriority” – set the post priority.
  • “setChangeFrequency” – set the post change frequency with daily, monthly, yearly.

You can read other options at spatie/laravel-sitemap package.

Update GenerateSitemap
Update Generate Sitemap

Step 7: Scheduled Command in Console Kernel

Now we nee to register this command to kernel for automatically generate XML sitemap. It can be scheduled in the console kernel to be run daily.

app/Console/Kernel.php

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    ...
    $schedule->command('sitemap:generate')->daily();
    ...
}
Register Command in Kernel
Register Command in Kernel

Step 8: Testing

We are all set, the sitemap is automatically set to be run daily. To set for now we are going to run the command to generate our sitemap manually by running the following command.

php artisan sitemap:generate

The above command will generate the sitemap.xml in public directory.

Run the following command to start the Artisan development server for laravel.

php artisan serve

And open the following link in any web browser to open the sitemap.

http://127.0.0.1:8000/sitemap.xml
How to Automatically Generate an XML Sitemap in Laravel
How to Automatically Generate an XML Sitemap in Laravel

Conclusion

This concludes our tutorial on How to Automatically Generate an XML Sitemap in Laravel. We hope you found it helpful. If you did, please share this article with your friends or family and leave us a comment to let us know what you think and stay tuned for more tutorials. If you like the tutorial please subscribe our youtube channel and follow us on social network facebook and instagram.

Share this:

One thought on “How to Automatically Generate an XML Sitemap in Laravel

Leave a Reply