Help us understand the problem. What is going on with this article?

TwitterでシェアするOGP画像を動的に書き換える

More than 1 year has passed since last update.

タイトルの通り、こんな要求があって何とか対応したので困ってる人のTipsになれば。。

※2019/07/31追記
ニッチな対応かと思いきや意外にも(少なくともSHIN_DEVELOPアカウントで一番)需要があるようなので
この記事はどんどんブラッシュアップしていきたい。

ogpってなんよ

SNSでシェアするときに使うアレよね?
って認識しかなかったのでちゃんと調べました。

OGPとは、Open Graph Protocolの略で、Facebookやmixi、Google+などのSNS上でWebページの内容を伝えるために定められたプロトコルです。
〜中略〜
OGPを使って画像やタイトル、説明文を適切に設定することで、共有されたユーザーへの訴求力が高まり、サイトへのアクセス数を増やし、より多くのユーザーに記事を見てもらうことが可能となります。

引用元:ナイル株式会社様HPより

まぁ大体合ってるので良しとしまして。

事の発端

とある投稿型のSPAを作成しまして、記事毎にogpの内容を切り替えたいという課題がありました。
ReactやらAjaxやらのjs周りに疎い私は
「おう、動的に変えたらええやん」
と、出来るならやっちゃいなよスタンスを取っておったわけですが、
よくよく話を聞いてみると、javascriptによる動的な切り替えはSNSを始めとしたクローラが解釈してくれないそうです。
つまりシェア時に、ogpで設定しておきたい画像やテキストが表示されないという
何ともみっともない事態が発生してしまうのですね。

これがどうやらバックエンド側なら解決出来るらしい、とのことなので
渋々色々調べたメモを残します(ここから本題)

やったこと

構成として各記事のURLにはIDがついてるので、これを使って記事データを取得して
phpでmeta情報を出力すりゃーいいんじゃねーかという調査結果を得ました。
http://onigiri-tabetai.jp/archives/123 ←コレ

前準備

まずクローラがシェア用のデータを取りに来た時だけ正しいogpをお持ち帰り出来るよう、
記事データとは全く別の領域にリダイレクトするようにしました。
.htaccessを以下のように設定しておきます。

※2019/07/31追記
ぐぐたすことGoogle+は個人向けサービス終了とのことで省略。
LINEのUAはfacebookexternalhitということなのでFB対応が同時にLINE対応になります。

RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest)
RewriteRule archives/(\d*)$ https://onigiri-tabetai.jp/head.php?id=$1 [L]

これによりシェア時にbotどもが来た際は全てhead.php?id=記事IDに誘導されます。

本体実装

head.phpは単純に出力処理を行っているだけです。
(フロントのソースコピペベースなので無駄が多いですが)
2019/05/18 結構閲覧されてるので大事なとこだけを整理しました。

<?php
$entry_id = ctype_digit($_GET['id']) ? $_GET['id'] : 0;
$ctrl = new dataController(); //この辺は省略

//個別に出力したい項目について定義
$data = [
            "title"        => "def_title",
            "main_caption" => "def_caption",
            "main_img"     => "def_img"
        ];
$data = $ctrl->getEntry($entry_id);
if ( count($data) <= 0 ){
    //entry_idに対応したデータが無かったらトップへ
    header('Location: http://onigiri-tabetai.jp/');
    exit());
}

createHead($data);

function createHead($data) {
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>おにぎりブログ</title>
    <!-- Google / Search Engine Tags -->
    <meta itemprop="name" content="<?php echo $data["title"]; ?>">
    <meta itemprop="description" content="<?php echo $data["main_caption"]; ?>">
    <meta itemprop="image" content="<?php echo $data["main_img"]; ?>">
    <!-- Facebook Meta Tags -->
    <meta property="og:url" content="http://onigiri-tabetai.jp/archives/<?php echo $data["id"] ?>">
    <meta property="og:type" content="website">
    <meta property="og:title" content="<?php echo $data["title"]; ?>">
    <meta property="og:description" content="<?php echo $data["main_caption"]; ?>">
    <meta property="og:image" content="<?php echo $data["main_img"]; ?>">
    <!-- Twitter Meta Tags -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="<?php echo $data["title"]; ?>">
    <meta name="twitter:description" content="<?php echo $data["main_caption"]; ?>">
    <meta name="twitter:image" content="<?php echo $data["main_img"]; ?>">
</head>
</html>

<?php
}
?>

連想配列に格納してforeachでkey,valueをぶん回したほうがスマートかもですねー。
これでどの記事をシェアしてもbotは記事IDを背負ってこのページに来るってスンポーです。
ここで出されたmeta情報をお持ち帰りしてまんまとシェア画像やテキストを作ることになります。

SHIN_DEVELOP
サーバーサイドのぷろぐらまー
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした