【Rails】 meta-tags と Cloudinary を使って動的にOGP画像を作る


今回「Yuppeing-App」という質問箱風のアプリを作ったのですが、シェアボタンからTwitterにシェアした時に、もらった質問の文をTwitter Card に、その回答をTweet文にするという機能を実装したので、まとめてみました。

出来上がりはこんな感じです🔽

環境

Gemfile
ruby '2.6.2'

gem 'rails', '6.0.0'

heroku へのデプロイ済みです。

デフォルトの meta 情報を設定する

1.meta-tags gem をインストール

この gem を入れると、head タグ内の meta タグをすっきりと整理することができます。

Gemfile
gem 'meta-tags'

追加してbundle installします。

2.default_meta_tagsを設定

app/helpers/application_helper.rb
module ApplicationHelper
  def default_meta_tags
    {
      site: 'Yuppeing App',
      title: 'Yuppyに質問してみよう!',
      reverse: false,
      charset: 'utf-8',
      description: 'Yuppy専用質問箱風アプリです。Yuppyに質問してみよう!',
      keywords: 'Yuppeing App, Yuppy, yuppy, Yuppyに質問',
      canonical: 'https://yuppeing-app.herokuapp.com/',
      separator: '|',
      icon: [
        { href: image_url('favicon.ico') }
      ],
      og: {
        site_name: :site,
        title: :title,
        description: :description,
        type: 'website',
        url: :canonical,
        image: image_url('ogp.png'),
        locale: 'ja_JP',
      },
      twitter: {
        card: 'summary',
        site: '@YuppyHappyToYou',
      }
    }
  end
end
設定するもの
site サイト名
title タイトル
reverse trueで、タイトル・サイト名の表示順が逆になる
charset 文字コード
description ページの説明
keywords ページのキーワード 「,」区切りで設定
canonical リンクタグをフルパスで設定
separator ウェブサイト名とページタイトルを区別するテキスト
icon favicon、apple用アイコンの設置
og:site_name サイト名 (siteと同じなら:site)
og:title 各ページのタイトル
og:description ページの説明
og:type ページの種類 ‘website’, ‘article’, ‘blog’など
og:url URLを設定
og:image シェア用の画像を設定
og:local リソースの言語を設定

meta-tags gem の README や、OGP設定に関する記事を見ながらお好みで値を設定してみてください。

app/views/layouts/application.html.erb
# headタグ内に置く
<%= display_meta_tags(default_meta_tags) %>

動的に OGP 画像を表示させる

使用方法のイメージは、背景画像を Cloudinary に保存、テキストは動的に@post.content を取り、背景画像の上に載せて表示させたものをOGP画像として設定します。

まず使用する gem をインストールしておきます。

Gemfile
gem 'cloudinary'
gem 'carrierwave'
$ bundle install

1. heroku に Cloudinary を アドオンする

HEROKU公式サイトに従い、以下コマンドでアドオンを追加します。

 $ heroku addons:create cloudinary:starter

Starter は Cloudinary のフリープランの名称です。

※HEROKU のダッシュボードの「Configure Add-ons」からも追加できます。

2. Cloudinary の設定

HEROKU にアドオン追加されたのが確認できたら、クリックして Cloudinary を開きます。

言語選択では Rails を選びます。

ダッシュボードの Account Details のところの yml をダウンロードします。

ダウンロードしたファイルを config ディレクトリに配置します。

この後、記載されている情報は環境変数に設定します。このまま公開することは絶対にしないで下さい。

環境変数の設定

Gemfile
gem 'dotenv-rails'

dotenv-railsを使う方は.env ファイルを作成し、以下のように書き設定します。

.env
CLOUDINARY_CLOUD_NAME = 取得したcloud_name
CLOUDINARY_API_KEY    = 取得したapi_key
CLOUDINARY_API_SECRET = 取得したapi_secret

その他、任意の方法で各自環境変数に設定してください。

heroku にも環境変数を登録

heroku で複数のアプリを所持されている方はアプリ名の指定をして設定します。

$ heroku config:set CLOUDINARY_CLOUD_NAME = 取得したcloud_name --app "指定したアプリ名"

または、HEROKU ダッシュボードの Settings の「Config Vars」からも簡単に設定できるのでお好きな方で。

3. 個別のOGP画像用URLを編集する

Cloudinary の Media Library にドラッグ&ドロップでOGP画像の背景となる画像を追加します。

リンクをクリックしてコピーします。

そのリンクのupload/より後ろに追加情報を入れていきます。

l_text:フォントの種類_フォントサイズ_ウェイト:背景画像に重ねるテキスト,その他オプション

参考: Cloudinaryの画像変換を極める

以下が、私のURLです。

https://res.cloudinary.com/私のCLOUDINARY_CLOUD_NAME/image/upload/l_text:Sawarabi%20Gothic_18:#{@post.content},co_rgb:6d3e12,w_380,c_fit/v1573396517/ogp-bg_merhm7.png

Sawarabi Gothic (スペースは%20に置き換えます)フォントの18px、配置するテキストはPostモデルの content (質問文)、フォントカラーは茶色を指定しました。
Google フォントから選べるそうなのですが、Sawarabi 系しか動作してくれませんでした😥

4. 個別のOGP画像用URLを set する

set_meta_tagを好きなページに配置して、先ほど作ったOGP画像用URLを埋め込みます。

app/views/posts/show.html.erb
<% if @replied %>
  <% set_meta_tags og: {image: "https://res.cloudinary.com/私のCLOUDINARY_CLOUD_NAME/image/upload/l_text:Sawarabi%20Gothic_18:#{@post.content},co_rgb:6d3e12,w_380,c_fit/v1573396517/ogp-bg_merhm7.png" },
              twitter: {card: 'summary_large_image'} %>
<% end %>

私の場合は、@replied(質問への返信) が存在するときだけこのOGP画像にしたかったのでif文をつけ、Twitter card の設定もデフォルトより大きめのものに変えています。

ローカル環境でエラーが出なければ、デプロイしてみてTwitter cardを確認してみましょう。

Cloudinary の「Media Transformations」に表示させたい文字がきているかも確認してみて下さい。

5. Twitter シェアボタンを配置する

app/views/posts/show.html.erb
<% if @replied %>
  <%= link_to "https://twitter.com/intent/tweet?text=#{@replied.content.truncate(118)}&url=#{request.url}/&hashtags=YuppeingApp&lang=ja", title: 'Twitter', class: "twitter-btn btn" do %>
    <i class="fab fa-twitter"></i> Twitterにシェア <i class="fas fa-external-link-alt"></i>
  <% end %>
<% else %>
  <%= link_to "https://twitter.com/intent/tweet?text=Yuppeing-App Yuppyに質問してみよう!&url=https://yuppeing-app.herokuapp.com/&hashtags=YuppeingApp&lang=ja", title: 'Twitter', class: "twitter-btn btn" do %>
    <i class="fab fa-twitter"></i> Twitterにシェア <i class="fas fa-external-link-alt"></i>
  <% end %>
<% end %>

Tweet 文に私の返信が載るようにしてあります。.truncate(118)で文字数を丸めています。返信がない場合はトップページにも置いてあるデフォルトのシェアボタンに設定しています。(もっとDRYにできるはずです😂)CSSは各自設定して下さい😉

以上です。是非試してみて下さい!