Ruby on Rails Open Graph Tags: Add OG Meta with content_for and Helpers
Add og:title, og:image, og:description, and Twitter card tags to Ruby on Rails apps using content_for, yield, and reusable view helpers.
Rails and OG tags
Ruby on Rails renders HTML on the server, so social crawlers receive your OG tags immediately — no JavaScript execution required. The standard Rails approach uses content_for in views and yield in the application layout to inject page-specific metadata.
Application layout with yield
In app/views/layouts/application.html.erb, add OG tag yield blocks with sensible defaults:
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title><%= yield(:title) || "My Rails App" %></title>
<meta name="description"
content="<%= yield(:description) || "Default description." %>">
<!-- Open Graph -->
<meta property="og:title"
content="<%= yield(:og_title) || "My Rails App" %>">
<meta property="og:description"
content="<%= yield(:og_description) || "Default description." %>">
<meta property="og:image"
content="<%= yield(:og_image) || asset_url("og-default.jpg") %>">
<meta property="og:url"
content="<%= yield(:og_url) || request.original_url %>">
<meta property="og:type"
content="<%= yield(:og_type) || "website" %>">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title"
content="<%= yield(:og_title) || "My Rails App" %>">
<meta name="twitter:description"
content="<%= yield(:og_description) || "Default description." %>">
<meta name="twitter:image"
content="<%= yield(:og_image) || asset_url("og-default.jpg") %>">
</head>
<body>
<%= yield %>
</body>
</html>Setting OG tags in views with content_for
<!-- app/views/posts/show.html.erb --> <% content_for :title, @post.title %> <% content_for :og_title, @post.title %> <% content_for :og_description, @post.excerpt %> <% content_for :og_image, asset_url(@post.cover_image) %> <% content_for :og_url, post_url(@post) %> <% content_for :og_type, "article" %> <article> <h1><%= @post.title %></h1> <%= @post.body %> </article>
Reusable helper method
For cleaner code, create a helper in app/helpers/application_helper.rb:
# app/helpers/application_helper.rb
module ApplicationHelper
def set_og_tags(title:, description:, image: nil, url: nil, type: "website")
content_for(:og_title, title)
content_for(:og_description, description)
content_for(:og_image, image || asset_url("og-default.jpg"))
content_for(:og_url, url || request.original_url)
content_for(:og_type, type)
end
end
<!-- In view: -->
<% set_og_tags(
title: @post.title,
description: @post.excerpt,
image: asset_url(@post.cover_image),
url: post_url(@post),
type: "article"
) %>Using the meta-tags gem
The meta-tags gem provides a DSL for managing all meta tags in Rails:
# Gemfile
gem 'meta-tags'
# In controller:
def show
@post = Post.find_by!(slug: params[:slug])
set_meta_tags(
title: @post.title,
description: @post.excerpt,
og: {
title: @post.title,
description: @post.excerpt,
image: asset_url(@post.cover_image),
url: post_url(@post),
type: 'article'
},
twitter: {
card: 'summary_large_image'
}
)
end
# In layout:
<%= display_meta_tags %>Common Rails OG mistakes
- Using image_url in non-asset-pipeline images: for user-uploaded images (e.g., via ActiveStorage), use
rails_blob_url(@post.cover_image)to generate absolute URLs. - Missing host in asset_url: in production, set
config.asset_hostinconfig/environments/production.rbso asset_url generates absolute URLs. - HTML entities in content: use
h()or ERB auto-escaping to prevent characters like&from breaking meta attributes.
Preview your OG tags free at OGFixer.com → Paste your Rails app URL to verify how your link card looks on Twitter, LinkedIn, Discord, and Slack.