How to Create Dynamic XML Sitemap in Laravel
Hello artisans, today I’ll discuss about sitemap in Laravel. We will see step by step how to create sitemap xml without any packages/plugins. And if you heard for a first time about sitemap, I request please check this article on Wikipedia. So, lets get started.
Note: Tested on Laravel 8.67.
Table of Contents
Creates Model
Create models, for that run the following command in your terminal.
php artisan make:model Post -m
php artisan make:model Category -m
php artisan make:model SubCategory -m
Prepare Migration
Prepare migrations by modifying the generated migrations file.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('slug');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('slug');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('categories');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSubCategoriesTable extends Migration
{
public function up()
{
Schema::create('sub_categories', function (Blueprint $table) {
$table->id();
$table->string('slug');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('sub_categories');
}
}
Finally, run the migration
php artisan migrate
Prepare Controller
Create a controller, for that run the following command in your terminal.
php artisan make:controller SitemapController
Now open the SitemapController and paste the below code.
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Post;
use App\Models\SubCategory;
class SitemapController extends Controller
{
public function index() {
$posts = Post::first();
$categories = Category::all()->first();
$subcategories = Subcategory::all()->first();
return response()->view('sitemaps.index', [
'posts' => $posts,
'category' => $categories,
'subcategory' => $subcategories,
])->header('Content-Type', 'text/xml');
}
public function articles() {
$post = Post::latest()->get();
return response()->view('sitemaps.article', [
'post' => $post,
])->header('Content-Type', 'text/xml');
}
public function categories() {
$category = Category::all();
return response()->view('sitemaps.category', [
'categories' => $category,
])->header('Content-Type', 'text/xml');
}
public function subcategories() {
$subcategory = Subcategory::all();
return response()->view('sitemaps.subcategory', [
'subcategories' => $subcategory,
])->header('Content-Type', 'text/xml');
}
}
Create Routes
Create necessary routes for that.
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('/sitemap.xml', [\App\Http\Controllers\SitemapController::class,'index'])->name('sitemap.xml');
Route::get('/sitemap.xml/post', [\App\Http\Controllers\SitemapController::class,'posts'])->name('post.xml');
Route::get('/sitemap.xml/category', [\App\Http\Controllers\SitemapController::class,'category'])->name('category.xml');
Route::get('/sitemap.xml/subcategory', [\App\Http\Controllers\SitemapController::class,'subcategory'])->name('subcategory.xml');
Create Views
Now create a folder inside resources/views named sitemaps and create 4 blade files
- index.blade.php
- post.blade.php
- category.blade.php
- subcategory.blade.php
Now paste the following codes into their corresponding view files:
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>http://127.0.0.1:8000/sitemap.xml/post</loc>
</sitemap>
<sitemap>
<loc>http://127.0.0.1:8000/sitemap.xml/category</loc>
</sitemap>
<sitemap>
<loc>http://127.0.0.1:8000/sitemap.xml/subcategory</loc>
</sitemap>
</sitemapindex>
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($categories as $category)
<url>
<loc>http://127.0.0.1:8000/article/category/{{ $category ->slug }}</loc>
<lastmod>{{ $category->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
@endforeach
</urlset>
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($subcategories as $subcategory )
<url>
<loc>http://127.0.0.1:8000/article/subcategory/{{ $subcategory ->slug }}</loc>
<lastmod>{{ $subcategory->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
@endforeach
</urlset>
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($posts as $content)
<url>
<loc>http://127.0.0.1:8000/article/{{ $content->slug }}</loc>
<lastmod>{{ $content->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
@endforeach
</urlset>
Now just visit the following slug to justify our sitemap content:
- http://127.0.0.1:8000/sitemap.xml
- http://127.0.0.1:8000/sitemap.xml/post
- http://127.0.0.1:8000/sitemap.xml/category
- http://127.0.0.1:8000/sitemap.xml/subcategory
That’s all for today. You can download this project from GitHub. Thanks for reading. ?
Comment
Preview may take a few seconds to load.
Markdown Basics
Below you will find some common used markdown syntax. For a deeper dive in Markdown check out this Cheat Sheet
Bold & Italic
Italics *asterisks*
Bold **double asterisks**
Code
Inline Code
`backtick`Code Block```
Three back ticks and then enter your code blocks here.
```
Headers
# This is a Heading 1
## This is a Heading 2
### This is a Heading 3
Quotes
> type a greater than sign and start typing your quote.
Links
You can add links by adding text inside of [] and the link inside of (), like so:
Lists
To add a numbered list you can simply start with a number and a ., like so:
1. The first item in my list
For an unordered list, you can add a dash -, like so:
- The start of my list
Images
You can add images by selecting the image icon, which will upload and add an image to the editor, or you can manually add the image by adding an exclamation !, followed by the alt text inside of [], and the image URL inside of (), like so:
Dividers
To add a divider you can add three dashes or three asterisks:
--- or ***

Comments (0)