← All framework guides

Ruby on Rails SEO: 7 checks and how to fix them

These are the Ruby on Rails-specific checks RankCLI runs, and the fix for each one in Ruby on Rails's own idiom. Ruby on Rails renders on the server by default, which removes a whole class of SEO problems before you start.

7 checks
server-rendered
SSR by default

Run all of these against your own site, free and without an account:

npx @rankcli/cli audit -u https://your-site.dev

What Ruby on Rails gives you for free

  • •Server-rendered HTML by default
  • •Turbo for fast navigation without SPA
  • •Strong conventions reduce mistakes
  • •Mature gem ecosystem

The checks

warning
RAILS_NO_META_TAGS_GEM

Not using meta-tags gem

The meta-tags gem provides a clean API for SEO tags.

Add meta-tags to Gemfile:

gem 'meta-tags'

Run bundle install, then:

# app/views/layouts/application.html.erb
<head>
  <%= display_meta_tags site: 'Your Site' %>
</head>
# In controllers or views
set_meta_tags title: 'Page Title',
              description: 'Page description',
              keywords: 'seo, rails'
warning
RAILS_NO_SITEMAP_GEM

Not using sitemap_generator gem

sitemap_generator creates SEO-friendly sitemaps automatically.

Add to Gemfile:

gem 'sitemap_generator'

Generate config:

rails sitemap:install

Configure config/sitemap.rb:

SitemapGenerator::Sitemap.default_host = "https://yoursite.com"

SitemapGenerator::Sitemap.create do
  add '/about', changefreq: 'monthly'
  Product.find_each do |product|
    add product_path(product), lastmod: product.updated_at
  end
end

Generate: rails sitemap:refresh

warning
RAILS_NO_CANONICAL

Missing canonical URLs

Rails apps with multiple URLs for same content need canonicals.

Add canonical tag in layout:

<!-- Using meta-tags gem -->
<%= display_meta_tags canonical: request.original_url %>

<!-- Or manually -->
<link rel="canonical" href="<%= request.original_url.split('?').first %>" />
notice
RAILS_TURBO_BREAKS_CRAWLERS

Turbo may affect JavaScript-dependent crawlers

Turbo Drive updates pages via JavaScript, which some crawlers may miss.

For SEO-critical pages, ensure content is in initial HTML.

For dynamic content, add data-turbo="false":

<%= link_to 'Critical Page', critical_path, data: { turbo: false } %>

Or disable for specific pages:

<meta name="turbo-visit-control" content="reload">
notice
RAILS_NO_JSON_LD

No structured data detected

Add JSON-LD for rich snippets.

Create a helper:

# app/helpers/seo_helper.rb
module SeoHelper
  def json_ld(data)
    content_tag :script, data.to_json.html_safe,
                type: 'application/ld+json'
  end
end

Use in views:

<%= json_ld({
  "@context" => "https://schema.org",
  "@type" => "Product",
  "name" => @product.name,
  "description" => @product.description
}) %>
warning
RAILS_SLOW_QUERIES

N+1 queries may slow pages

Slow pages hurt SEO. Use includes/eager_load.

Use bullet gem to detect N+1:

# Gemfile
gem 'bullet', group: 'development'

Fix with includes:

# Before (N+1)
@posts = Post.all
@posts.each { |p| p.author.name }

# After (2 queries)
@posts = Post.includes(:author).all
notice
RAILS_NO_CACHING

Page caching not configured

Rails caching can dramatically improve response times.

Enable caching in production:

# config/environments/production.rb
config.action_controller.perform_caching = true
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }

Use fragment caching:

<% cache @product do %>
  <%= render @product %>
<% end %>

Check your own Ruby on Rails site

280+ checks including every one above. No signup, nothing leaves your machine.

Run a free audit