Generate a Simple XML Sitemap Using Laravel

7 years ago by Filip Zdravkovic

Laravel XML Sitemap Laraget.com

You probably already know that a sitemap is a file where you can list the web pages of your site to tell Google and other search engines about the organization of your site content. Search engine web crawlers like Googlebot read this file to more intelligently crawl your site.1

In particular, we are interested in XML format of sitemap. The Sitemap must:2

  • use UTF-8 encoding.
  • begin with an opening <urlset> tag and end with a closing </urlset> tag.
  • specify the namespace (protocol standard) within the <urlset> tag.
  • include a <url> entry for each URL, as a parent XML tag.
  • include a <loc> child entry for each <url> parent tag.

Here is an example of the most simple sitemap:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
<url>
    <loc>https://laraget.com/</loc>
</url>
<url>
    <loc>https://laraget.com/blog</loc>
</url>
<url>
    <loc>https://laraget.com/about-me</loc>
</url>
<url>
    <loc>https://laraget.com/demos</loc>
</url>
</urlset>


Every sitemap XML file must begin with:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">


and must end with:

</urlset>


In between we specify fully-qualified URLs that are inside of <url><loc> tags:

<url>
    <loc> fully-qualified URL  - for example: https://laraget.com/about-me</loc>
</url>


You can specify other tags that are not required but can help crawlers. Here you can find more details about the tags that can be optional. In my case (for laraget.com), I didn’t use these tags, although most people use them.

Also, when you finish reading this post, you should read general sitemap guidelines where it is explained which URLs should, and which URLs should not be be specified (for example, in case where you have a multilingual website). Be sure to read this!

Let's go back to creating XML sitemap for laraget.com. There are the following pages:

BUT, there are also blog posts that are created weekly or daily, and every blog post has its own unique URL which means that we have two options for specifying in the XML sitemap:

  1. to do it manually, every time you create a blog post you will need to edit the XML sitemap file and specify new URL for that blog post;
  2. or to automatically specify the URLs in the sitemap.

Of course, we are interested in second option. And, it's very simple - if we assume that each blog post has its own slug - then we would be able to specify URLs as follows:

@foreach($posts as $post)
    <url>
        <loc>https://laraget.com/blog/{{ $post->slug }}</loc>
    </url>
@endforeach


So, let’s define a blade view in resources/views/pages/sitemap.blade.php:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://laraget.com/</loc>
    </url>
    <url>
        <loc>https://laraget.com/blog</loc>
    </url>
    <url>
        <loc>https://laraget.com/about-me</loc>
    </url>
    <url>
        <loc>https://laraget.com/demos</loc>
    </url>
    @foreach($posts as $post)
        <url>
            <loc>https://laraget.com/blog/{{ $post->slug }}</loc>
        </url>
    @endforeach
</urlset>


IMPORTANT:
Since we use PHP (.blade.php) in combination with XML, you need to make sure that the Short Open Tag option (<?) is disabled. In most cases this option is already disabled by default and it is only available if enabled using the short_open_tag php.ini configuration file directive (or if PHP was configured with the --enable-short-tags option). If, for some reason, you need to have the Short Open Tag option enabled,  you can print the XML prolog in this way: <?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>.

Now you can create a new controller just for that sitemap (for example, you can create SitemapController) or you can use any other controller you created earlier. In my case, I used PagesController where I defined the following method:

public function sitemap()
{
    $posts = Post::where('visible', 1)->orderBy('updated_at', 'DESC')->get();
    return response()->view('pages.sitemap', compact('posts'))->header('Content-Type', 'text/xml');
}


Finally, in app/Http/routes.php (or if you are using Laravel 5.3 in routes/web.php):

Route::get('/sitemap.xml', 'PagesController@sitemap');


and that is all! Pretty simple, right? This is how I created my XML sitemap, and you can take a look at it here: https://laraget.com/sitemap.xml

IMPORTANT: Sitemaps should be no larger than 10MB (10,485,760 bytes) and can contain a maximum of 50,000 URLs. These limits help to ensure that your web server does not get bogged down serving very large files. This means that if your site contains more than 50,000 URLs or your Sitemap is bigger than 10MB, you must create multiple Sitemap files and use a Sitemap index file. You should use a Sitemap index file even if you have a small site but plan on growing beyond 50,000 URLs or a file size of 10MB (which is something that will probably never happen to Laraget.com). A Sitemap index file can include up to 1,000 Sitemaps and must not exceed 10MB (10,485,760 bytes). You can also use gzip to compress your Sitemaps.3

If you want to use (generate) index style sitemaps, there is a good article written by Eric L. Barnes: https://laravel-news.com/2016/09/laravel-sitemap/


View All Blog Posts Here