Having the right SEO meta tags generated for your website is a must have nowadays. Here we show how to get them set easy and fast with the help of the meta-tag gem.

The need for SEO meta tags

Metatags live in the head section of each one of your website pages and hold important information towards the correct indexation and positioning on search engines like Google or Bing, but also give you control on how your website looks like when it’s shared on social media sites like Facebook or Twitter, which might also define their own set of tags. This shows how important they are, since they help you engage your potential customers better and present your website just how you want it.

Meta tags in Rails applications

Luckily us Rails developers can rely on the Meta-Tags gem by Dmytro Shteflyuk to access the wide variety of avaialble tags and set our own. The readme file for the gem has a very comprehensive list of tags and how to set them, and here we’ll describe how we set them across an example application.

All relies on the Application Controller

What we do is set up a method that we will call on each action across our website, that sets the default tags, like this:

class ApplicationController < ActionController::Base
  # ...
  before_action :prepare_meta_tags, if: "request.get?"

  def prepare_meta_tags(options={})
    site_name   = "CookiesHQ"
    title       = [controller_name, action_name].join(" ")
    description = "The CookiesHQ team creates web software for humans"
    image       = options[:image] || "your-default-image-url"
    current_url = request.url

    # Let's prepare a nice set of defaults
    defaults = {
      site:        site_name,
      title:       title,
      image:       image,
      description: description,
      keywords:    %w[web software development mobile app],
      twitter: {
        site_name: site_name,
        site: '@thecookieshq',
        card: 'summary',
        description: description,
        image: image
      og: {
        url: current_url,
        site_name: site_name,
        title: title,
        image: image,
        description: description,
        type: 'website'


    set_meta_tags options
  # ...

Now, to show the tags on our views, we would need to use the display_meta_tags method on the head section of our layout:

  = display_meta_tags
  %meta(http-equiv="X-UA-Compatible" content="IE=edge,chrome=1")

And we’re set! We should be seeing already tags (also for Twitter and Facebook!) when inspecting our site with the developer tools of your browser. Also, on the title of our page, in the browser tab, we’ll see something like “The Cookie Shop | The Cookie Shop”. This uses the scheme site | title, unless you use the reverse option on one of your calls, as we did when we set the title, in which case the two parameters will appear inverted. We’ll see this clearer on the next examples.

Setting different tags for different parts of our site

SEO rules recommend having different tags for each part of our site, so search engines know more about our site and it can be properly indexed and positioned. Now that we have our prepare_meta_tags method set, we can use it on other controllers’ methods:

class ProductsController < ApplicationController
  # ...
  def index
    prepare_meta_tags title: "Products", description: "Find on this page all our lovely products"

  def show
    @product = Product.find params[:id]

    prepare_meta_tags(title: @product.name,
                      description: @product.description,
                      keywords: @product_keywords,
                      image: @product.picture.url(:large),
                      twitter: {card: "summary_large_image"})
  # ...

Or we can use three instance variables that the gem uses:

class ProductsController < ApplicationController
  # ...
  def index
    @page_title = "Products"

  def show
    @product          = Product.find params[:id]
    @page_title       = @product.name
    @page_description = @product.description
    @page_keywords    = @product.keywords
  # ...

Another way of doing this would be on your views, using the corresponding methods to set the title and description, for example.

- title 'Products'

  = description "This is our product range"

Note that we can either just set the variable value (as with title) or setting it and using it on the view, as we did with the description.

Above you can see a couple of simple examples on how to use the method to easily set tags on each page. For our index method, the title of our page would be “Products | The Cookie Shop” and the description would stay the same. If we wouldn’t have used the reverse option before, we would have “The Cookie Shop | Products”, that also makes sense, but would be cut off on our browser tab, so we would be seeing always the same text, loosing the point of changing the title tag.

Furthermore, for showing a single product as in the above example, we would be also using the product description as description for our page. We could go further and set the image meta-tag to be a picture of the product itself, depending on what we want. There are a lot of options available.

A word about Turbolinks

There are several threads out there about how to make a site with Turbolinks change all the SEO tags when you browse it. Changing just the title (which works out of the box) should suffice for a human user, since it’s the only part they’re really going to see, so there’s no real point on trying to force changing any other tag when browsing the site.

And for things like the description or images, webcrawlers do not use Javascript to browse a site in order to produce the information needed, they’ll get each page as a new access. So if the tags are set and you see them if you access that certain page directly, it should work just OK.


I hope you find this post as useful as the Meta-Tags gem is. It really helps a lot to get an habitual chunk of work done on most websites in almost no time.

Any comments or thoughts? Don’t hesitate to share them!

Image SEO Scrabble by Jonathan Rolande on Flickr used under CC BY 2.0

Join the discussion One Comment