Automatically generating a sitemap for your Laravel wink blog

Hi Folks! like I have tweeted a while back, I really really want to blog as much as possible in 2020.

It doesn't mean I can just get away with content writing, though that's exactly what I want to do. 😂

I need to brush up my SEO skills as well, I am planning to write about this in details in a future post but for now I am going to talk about how I am managing to generate a sitemap for my Laravel wink blog. Well, it doesn't have to be a Laravel wink blog, but I chose wink because it's a distraction free writing tool. I really love it. Also it's from one of my favourite open source developer Mohamed Said, Also know as @themsaid on twitter. If you're a Laravel developer then you shall follow him. Totally worth it.

Enough about the chit chat, let's summarise what we are going to do today.


  1. Installing spatie/laravel-sitemap
  2. Prepping your sitemap generation
  3. Automate the sitemap generation
  4. Conclusion

Step 1: Installing spatie/laravel-sitemap

Just like every other common Laravel problem & solution, Spatie has a solution for this as well. #loveSpatie #respectFreek ❤️

Of course you can find more in depth information about this package from the documentation, my goal here is to simply hook this to my Laravel Wink blog. So I will not repeat the entire README of the package 📦.

Let's start by installing the package with composer.

composer require spatie/laravel-sitemap

Step 2: Prepping your sitemap generation

Since I want to automate this process, I am going to generate an artisan command, the idea here is to run the command periodically with the scheduler and generate the sitemap.

Let's generate an Artisan command by running php artisan make:command SitemapGenerator

This will create a file /app/Console/Commands/SitemapGenerator.php in your project.

Now we can update the handle() method to make out sitemap.xml file.


namespace App\Console\Commands;

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

class SiteMapGenerate extends Command

     * The name and signature of the console command.
     * @var string
    protected $signature = 'sitemap:generate';

     * The console command description.
     * @var string
    protected $description = 'Command description';

     * Create a new command instance.
     * @return void
    public function __construct()

     * Execute the console command.
     * @return mixed
    public function handle()

        $sitemap = Sitemap::create();

        $posts = WinkPost::select(['slug', 'updated_at'])
            ->where('published', 1)

        foreach ($posts as $post) {

            $sitemap->add(Url::create('/blog/' . $post->slug)->setLastModificationDate($post->updated_at));




Note that the Url::create('/blog'. $post->slug) in the above snippet, I am using the post slug to generate my blog urls. You can specify your blog url generation scheme here. I prefer slugs because it's SEO friendly than the UUID.

Now you can run php artisan sitemap:generate command to generate a sitemap.xml file in your public folder.

Step 3: Automate the sitemap generation

Automating the sitemap is actually is an easy part. You can do it in many ways, you can set it up as part of your deployment or you can add the command in the task schedular and execute it periodically or you can even do it in an observer where each time you publish a post it triggers the artisan call.

But I am going to show you a simple way to generate sitemap daily. Let's face it, I write only one post per day at best. So this fits perfectly for me. Feel free to change the frequency of your choice. 👨‍💻

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)

Step 5: Conclusion

That's it. You are all set. There is one last thing. Please please please go check the docs at there are lot of cool options you can pick for sitemap generation. Also leave spatie a star when you are there. 🙃

Feel free to comment here if you have any questions or suggestions. If you get any issues don't break your head. I can help you debug your code. Feel free to request a session from me on codementor. 

I'll see you in another post. Have a nice day :) 

Related articles

Signature Pad with Alpine.js

The post describes the implementation of signature pads with Alpine.js. It also discusses how to integrate it with laravel livewire.