Sitemaps are very important, search engines such as Google read the sitemap file to crawl your site more efficiently. Sitemaps tell which pages and files, you think are important in your website but how can we create a sitemap in a Laravel website.
It’s so easy to code your sitemap generator in Laravel without needing a package. We will create a route for the sitemap and a controller for preparing all the URLs and information we need for passing them to a view that will generate an XML file.
XML schema for the Sitemap protocol
Let’s see the XML schema for the Sitemap protocol.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.example.com/</loc>
<lastmod>2021-01-28</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
</urlset>
<url>
The parent tag for each URL entry and it’s required.<loc>
The URL of the page. This URL must begin withhttp / https
and it’s required.<lastmod>
The date of last modification of the file usingYYYY-MM-DD
format and it’s optional.<changefreq>
How frequently the page is likely to change, values are (always – hourly – daily – weekly – monthly – yearly – never) and it’s optional.<priority>
The priority of this URL relative to other URLs on your site, values range from 0.0 to 1.0 and it’s optional. But note that the position of your URLs in a search engine’s result pages will not be effected with the priority here.
Creating Laravel sitemap
Now, we understand the information we need to generate the sitemap, we need to create a sitemap controller.
php artisan make:controller SitmapController
let’s create the route in web.php on your Laravel application for the sitemap, the URL search engines need for your sitemap.
use App\Http\Controllers\SitmapController;
//
Route::get('/sitemap',[SitmapController::class, 'index'])->name('sitemap');
//
In SitmapController
, we will add the index function, and inside it, we will get all the routes we need for the sitemap, In Laravel, we have basic routes that take no parameters such as (/contact
, /about
) we will right them manually or we can get them via app('router')->getRoutes()
and we have routes that take a parameter such as (/posts/{slug}
) that are mostly coming from databases so we will use an Eloquent model.
This is how should be our controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class SitmapController extends Controller
{
public function index(){
$routes = app('router')->getRoutes();
$posts = Post::all();
// return $arrays=(array) $routes; /*uncomment to test $routes*/
return response()->view('sitmap', [
'routes' =>$routes,
'posts' =>$posts,
])->header('Content-Type', 'text/xml');
}
}
We won’t return a normal Laravel view, we will return an XML file so we used the response()
and changed the header Content-Type
to text/xml
. here is what our sitmap.blade.php should look like.
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/</loc>
<lastmod>2021-01-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://example.com/contact</loc>
<lastmod>2021-01-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
@foreach ($routes as $item)
@if($item->action['prefix'] =="/html" || $item->action['prefix'] =="/css")
<url>
<loc>{{url('/'.$item->uri)}}</loc>
<lastmod>2021-01-28</lastmod>
<changefreq>yearly</changefreq>
<priority>0.9</priority>
</url>
@endif
@endforeach
@foreach ($posts as $post)
<url>
<loc>{{url('posts/'.$post->slug)}}</loc>
<lastmod>{{$post->updated_at}}</lastmod>
<changefreq>yearly</changefreq>
<priority>0.9</priority>
</url>
@endforeach
</urlset>
I give you some different ideas about how we generate our URLs and how we filter our routes, treat the view as a normal blade with @foreach
and @if
to reach the result you want. I hope I could help.