Generate an XML Sitemap with Ruby on Rails 7

In this post, we'll generate an XML sitemap for a Ruby a Rails blog application. We'll use Rails 7.0.3 and Ruby 3.1.2.

Generate a New Application

First, let's create our application. From the terminal type:

rails new my_blog

Let's change the directory to our application folder:

cd my_blog

Generate a Post Scaffold

Let's quickly generate a Post scaffold:

bin/rails g scaffold Post title:string content:text

Let's run the migration:

bin/rails db:migrate

Set The Root Route

Let's set the root route of the application to the Posts index action. In the routes.rb file in the config/ folder, let's add this at the top:

root 'posts#index'

Order Posts by Creation Date

Usually, a blog application orders posts by the creation date, so let's do that. Let's first add a method in the post.rb file in the app/models/ folder to sort the posts:

def self.by_date
  order('created_at DESC')
end

Then, let's modify the index method in the posts controller to make use of this method:

@posts = Post.all.by_date

Generate a Pages Controller with A Sitemap Method

We'll create a pages controller with a sitemap method. In the terminal, we type:

bin/rails g controller Pages sitemap

Let's edit the route to this action in theconfig/routes.rb file as follows:

get 'sitemap', to: 'pages#sitemap', defaults: {format: 'xml'}

Let's rename the automatically generated view from sitemap.html.erb to sitemap.xml.erb

Edit The Sitemap VIEW in the app/views/pages FOLDER

Let's also delete the content that Rails generated when it generated this view. And let's start edit it. Let's add first an XML declaration at the top of the file:

<?xml version="1.0" encoding="UTF-8"?>

A sitemap begins with a opening <urlset> tag and end with a closing </urlset> tag. Let's add these tags to our sitemap after the XML declaration:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
</urlset>

Now, between these two tags, let's add our application URLs inside <url> tags. First, we add the root route. Only one child of the <url> tag is required: the <loc> tag. It represents the URL of the page. Others are optional.

First, we'll add the URL of the home page. For this, we'll use the Rails  _url helper:

<url>
  <loc><%= root_url %></loc>
</url>

Then we'll use the Ruby each method to iterate through our posts, so when we add a new post to our blog, it will be added to our sitemap as well. But before we do that, let's make first a @posts instance variable available inside the sitemap method in the pages controller:

@posts = Post.all.by_date

And then, in the sitemap view, after the root URL we add the posts URLs:

 <% @posts.each do |post| %>
   <url>
     <loc><%= post_url(post) %></loc>
   </url>
 <% end %>

This is the final sitemap.xml.erb view:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc><%= root_url %></loc>
  </url>
  <% @posts.each do |post| %>
    <url>
      <loc><%= post_url(post) %></loc>
    </url>
  <% end %>
</urlset>

We can now start the server:

bin/rails s

And go to http://localhost:3000/sitemap.xml to check it.

 

Post last updated on May 13, 2023