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.