How to Build a Google Sitemap for your Ruby on Rails App

How do you get search engines like Google to know how to index the pages on your awesome site? You provide those search engines with a sort of table of contents called a Sitemap. And I'll show you how to add one to your Ruby on Rails application.

Sure, there are gems that will do this for you. They will generate a file called sitemap.xml and place it into your public folder. But if you're like me and deploying to Heroku, you'll have a hard time keeping this file correct for your production environment. The problem I experienced was when I tried to generate the sitemap for my environment on Heroku, Heroku doesn't allow you to deviate from the files in your git repository or place any new files on its machines.

I decided to make the sitemap myself, dynamically, using a controller. This way, there's no environment-specific files Heroku has to keep on its machine, and I don't have to regenerate the sitemap every time I add content to my site. Google won't care if I'm showing it my sitemap through a static page or dynamic page—as long as it's in a format it cares about. You can find the guidelines for what Google expects here.

In this tutorial I will be using an example of my website, which has the following pages that need to be indexed: home page, about page, and a page for every blog post. Let's get to it!

  1. Add the sitemap route to your routes.rb: get '/sitemap' => 'sitemaps#index'
  2. Create the Sitemaps Controller file:

    class SitemapsController < ApplicationController
      skip_before_action :authenticate_user!
    
      def index
        @host = "#{request.protocol}#{request.host}"
        @posts = Post.all
      end
    end
    

    Note that I told the controller to skip authenticating the user. Google needs to be able to get to your Sitemap without having to log in.

  3. Since it needs to be in xml format, you'll want to create your view with a .xml.erb file format. Create an index.xml.erb view for the sitemaps_controller, and add the following to it:

    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
       <url>
          <loc><%= @host %></loc>
       </url>
       <url>
          <loc><%= "#{@host}#{about_path}" %></loc>
       </url>
       <url>
          <loc><%= "#{@host}#{posts_path}" %></loc>
       </url>
       <% @posts.each do |post| %>
         <url>
            <loc><%= "#{@host}/posts/#{post.id}" %></loc>
         </url>
       <% end %>
    </urlset>
    

    This will add all of my pages: the root path, the about path, the path that displays all of my posts, and a path for every post.

  4. Now if you spin up your rails server and go to localhost:3000/sitemap.xml, you should see your generated sitemap.

  5. Go to Google webmaster, and submit this sitemap once it is pushed to your production environment.

And that's all. Just note that you will need to resubmit your sitemap to Google every time you add more pages to your application. There's a way to automate this—like a daily cron that pings http://www.google.com/webmasters/sitemaps/ping?sitemap=[your sitemap web address].