はじめに
Ruby on Railsでアプリを作成した時にgemを使ってメタタグを導入しました。
gem meta-tagsはtitleも自動で作ってくれる仕様のようです。titleの動的表示に手こずったので備忘録も兼ねてここに記します。
この記事はプログラミング初心者が書いています。何か間違ったことがありましたらご指摘いただければ幸いです。
作成したアプリ:https://sky-photos.onrender.com/
Github:https://github.com/tantp-1111/sky_photos
環境
mac OS
Rails 7.2.2.2
Ruby 3.3.6
Docker環境
gem meta-tags導入
Gemfileに
gem "meta-tags"
を記入し、bundle install。
次にbundle exec rails g meta_tags:installで設定ファイルconfig/initializers/meta_tags.rbができる。
このファイルはデフォルトの設定を上書きしたい時に使うファイルで、今回特に触っていません。
ヘルパーにdefault_meta_tagsメソッドを記述
module ApplicationHelper
# メタタグ,動的OGP
def default_meta_tags
base_title = "SkyPhotos"
title = content_for?(:title) ? content_for(:title) : ""
description = "ふと見上げた空を共有しよう。空の写真を投稿できるアプリ「Skyphotos」"
{
site: base_title,
title: title,
reverse: true,
charset: "utf-8",
description: description,
keywords: "空, 写真, エモい, sky, photos, 共有",
og: {
site_name: base_title,
title: title,
description: description,
type: "website",
url: request.original_url,
image: ogp_image_url,
locale: "ja-JP"
},
twitter: {
card: "summary_large_image",
image: ogp_image_url
}
}
end
# 動的OGP画像,cloudinaryに保存された画像引っ張ってくる
def ogp_image_url
if @post&.id
public_id = @post.image.key
cloud_name = Rails.application.credentials.dig(:cloudinary, :cloud_name)
return "https://res.cloudinary.com/#{cloud_name}/image/upload/#{public_id}.jpeg"
end
# デフォルトOGP画像
image_url("default_sky.png")
end
end
def default_meta_tagsのtitle部分解説します。
最初に変数を定義しています。
base_title = "SkyPhotos"
title = content_for?(:title) ? content_for(:title) : ""
titleはビュー側で設定されたタイトルを取得しています。
content_for(引数)?で引数のコンテンツがキャプチャされているかどうかをチェックし、三項演算子を使って条件分岐しています。
例えば詳細ページに飛んだ時、show.html.erbには
<% content_for(:title, @post.title) %>
と記述しており、投稿のタイトルによって動的にページタイトルを変更させています。
詳細ページでのtitleは
title = content_for?(:title) ? content_for(:title) : ""がtrueとなり、title = content_for(:title)となります。
一方でtopページは、show.html.erbのようにタイトルコンテンツを用意していないためfalseとなり、title = ""(空文字)になります。
例として「hogehoge」というタイトルの投稿をしたとします。
ブラウザの検証ツールElementsタブのheadタグを確認してみると
詳細ページ
<title>hogehoge | SkyPhotos</title>
topページ
<title>SkyPhotos</title>
と表示されます。なのでわざわざ
title: title.present? ? "#{title} | #{base_title}" : base_title
と記述しなくてもgemのデフォルト設定で「ページタイトル | サイト名」としてくれるようです。
なお、
reverse: true
により「ページタイトル | サイト名」の表示順を指定しています。
デフォルトは「サイト名 | ページタイトル」
また、titleを配列で渡す方法もあります。
title: ["詳細", title]
<title>hogehoge | 詳細 | SkyPhotos</title>
headタグ内にメタタグ設定default_meta_tagsを出力させる
<%= display_meta_tags(default_meta_tags) %>
を記述して全てのviewに表示させます。
参考記事