WTF are meta tags?

Setup in a Rails app
- how to simply setup default meta tags for any of your website's pages,
- how to override them in some pages to be more specific and impactful.
Default Meta Tags
# config/meta.yml meta_product_name: "Product Name" meta_title: "Product name - Product tagline" meta_description: "Relevant description" meta_image: "cover.png" # should exist in `app/assets/images/` twitter_account: "@product_twitter_account" # required for Twitter Cards
Let's create a default_meta.rb file in config/initializers in which we load the content as a Hash in a DEFAULT_META Ruby constant.
# config/initializers/default_meta.rb # Initialize default meta tags. DEFAULT_META = YAML.load_file(Rails.root.join("config/meta.yml"))
Important: as any file in the config/initializers folder, it is loaded when your app is launched. Any time you change the content in meta.yml, restart yourrails s to refresh DEFAULT_META!
Helpers setup
# app/helpers/meta_tags_helper.rb module MetaTagsHelper def meta_title content_for?(:meta_title) ? content_for(:meta_title) : DEFAULT_META["meta_title"] end def meta_description content_for?(:meta_description) ? content_for(:meta_description) : DEFAULT_META["meta_description"] end def meta_image meta_image = (content_for?(:meta_image) ? content_for(:meta_image) : DEFAULT_META["meta_image"]) # little twist to make it work equally with an asset or a url meta_image.starts_with?("http") ? meta_image : image_url(meta_image) end end
Important: production host setup for images absolute urls
Rails image_url helper requires you setup your host to generate the absolute urlneeded to load your images from the external world (Facebook, Twitter, ...).
# app/controllers/application_controller.rb def default_url_options { host: ENV["DOMAIN"] || "localhost:3000" } end
heroku config:set DOMAIN=www.my_product.com
You can check it's properly set with heroku config:get DOMAIN.
HTML setup - Layout
Finally, open your layout app/views/layouts/application.html.erb and copy paste the following meta tags in your layout's <head>:
<title><%= meta_title %></title> <meta name="description" content="<%= meta_description %>"> <!-- Facebook Open Graph data --> <meta property="og:title" content="<%= meta_title %>" /> <meta property="og:type" content="website" /> <meta property="og:url" content="<%= request.original_url %>" /> <meta property="og:image" content="<%= meta_image %>" /> <meta property="og:description" content="<%= meta_description %>" /> <meta property="og:site_name" content="<%= meta_title %>" /> <!-- Twitter Card data --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="<%= DEFAULT_META["twitter_account"] %>"> <meta name="twitter:title" content="<%= meta_title %>"> <meta name="twitter:description" content="<%= meta_description %>"> <meta name="twitter:creator" content="<%= DEFAULT_META["twitter_account"] %>"> <meta name="twitter:image:src" content="<%= meta_image %>">
HTML setup - Views
Now let's assume you have an Offer model and you want dynamic titles and descriptions for any products#show page. Just set the relevant content_fors in app/views/offers/show.html.erb:
<!-- app/views/offers/show.html.erb --> <% content_for :meta_title, "#{@offer.name} is on #{DEFAULT_META["meta_product_name"]}" %> <% content_for :meta_description, @offer.description %> <% content_for :meta_image, cl_image_path(@offer.photo.path) %>
Testing
It's time to deploy your code and test your setup.
That's all folks
This sets a framework to easily manage your meta tags in every single page of your website. It's now up to you to keep on setting relevant titles, descriptions and images every time you code a new view!
