なにこれ

Gatsby製ブログ(Reactアプリ)でSNS対応した時のメモです。
(1) SNSシェアボタン(2) 自分のSNSへのリンクを設置して、ブログの記事をSNSでシェアできるように、、、
また、(3) OGPタグを設定し、SNSでシェアするときにイメージ画像や、タイトル、記事概要を表示できるようにしました。

  • ブログのフッター ブログフッタ
  • Twitterの呟き つぶやきサンプル

1. SNSシェアボタンを設置

Facebook、Google、Linkedin、Twitterシェアボタン

react-shareでめっちゃ簡単にできます。
それぞれ専用タグが用意されているので
url属性に記事のURL、icon属性にアイコンサイズを指定するだけです。
Linkedinアイコンはそれに加えてtitle属性に記事タイトルを
Twitterアイコンはvia属性に自分のTwitterアカウント名、title属性に記事タイトルを指定します。
※下記コード中のarticleUrlは記事URL、articleTitleは記事タイトルです。

<FacebookShareButton url={articleUrl}>
  <FacebookIcon size={32} round />
</FacebookShareButton>

<GooglePlusShareButton url={articleUrl}>
  <GooglePlusIcon size={32} round />
</GooglePlusShareButton>

<LinkedinShareButton url={articleUrl}>
  <LinkedinIcon title={articleTitle} size={32} round />
</LinkedinShareButton>

<TwitterShareButton title={articleTitle} via="@inouetakumon" url={articleUrl}>
  <TwittearIcon size={32} round />
</TwitterShareButton>

すると下記のように画面にSNSシェアアイコンが表示されます。

SNSシェアアイコン

はてブ追加ボタン

bookmark_button.jsというJavaScriptファイルを読み込んで、リンクタグを設置するだけです。

<Helmet>
  <script type="text/javascript" src="//b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async" />
</Helmet>
<a
  href="http://b.hatena.ne.jp/entry/"
  className="hatena-bookmark-button"
  data-hatena-bookmark-layout="vertical-normal"
  data-hatena-bookmark-lang="ja"
  title="このエントリーをはてなブックマークに追加"
  >
  <img
    src="//b.st-hatena.com/images/entry-button/button-only@2x.png"
    alt="このエントリーをはてなブックマークに追加"
    width="20"
    height="20"
    style={{border: 'none'}}
  />
</a>

すると下記のように画面にはてブ追加アイコンが表示されます。 ![はてブシェアアイコン](./hatebu1.png)

クリックするとウィジェットが表示されます。(bookmark_button.jsがやってくれています。) はてブシェアアイコンウィジェット

2. 自分のSNSへのリンクを設置

SNSへのリンクアイコンはreact-fontawesomeを使いました。
まずはreact-fontawesomeをインストールします。

npm install --save @fortawesome/react-fontawesome
npm install --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-brands-svg-icons
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/free-regular-svg-icons

実装は下記のようにします。スタイルの細かい部分は省略していますが、ざっくり書きのような感じです。Qiitaだけ小細工してます。
GitHub Font Awsomeアイコン使用。背景をダークグレイ。
Twitter Font Awsomeアイコン使用。背景を水色。
Qiita Font Awsomeに用意がないので、代わりに虫眼鏡アイコン使用。背景を黄緑にしてQiitaっぽくする
・・・

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faGithubSquare, faTwitterSquare } from '@fortawesome/free-brands-svg-icons'
import { faSearch } from '@fortawesome/free-solid-svg-icons'

・・・

class Bio extends React.Component {
  render() {
    return (
      ・・・
      <a href="https://github.com/Takumon">
       <FontAwesomeIcon
         color="#333"
         icon={faGithubSquare} />
      </a>

      <a href="https://twitter.com/inouetakumon">
        <FontAwesomeIcon
          color="#3eaded"
          icon={faTwitterSquare} />
      </a>

      <a href="https://qiita.com/Takumon">
        <FontAwesomeIcon
          color="white"
          style={{
            overflow: 'hidden',
            height: '0.9em',
            width: '0.9em',
            backgroundColor: '#4cb10d',
            borderRadius: '2px',
            marginTop: '2px',
          }}
          icon={faSearch} />
      </a>

      ・・・
    );
  }
}

ここまでくると、下記のようなアイコンが画面に追加されています。

自分のSNSリンク

3. OGPタグを設定

OGPとは、「Open Graph Protcol」の略でFacebookやTwitterなどのSNSでシェアした際に、 WEBページのタイトルやイメージ画像、説明文などをわかりやすく伝えるためのHTML要素です。 OGPをWebページで設定することでユーザーに対してWEBページの内容を詳しく伝えることができます。

OGPタグを定義

Reactアプリだと、ReactHelmetを使います。
今回はOgpタグを作りました。ただブログのトップと記事詳細で設定する値が違うので、そこはコンポーネントの引数で受け取れるようにしています。
blog-config.jsはブログタイトルなどの設定しているファイルです。

import React from 'react'
import Helmet from 'react-helmet'

import {
  blogTitle,
  blogUrl,
  blogDescription,
  blogImageUrl,
  facebookAppId,
  blogAuthorTwitterUserName,
} from '../config/blog-config.js';

export default function Ogp({isRoot, title, description}) {
  const type = isRoot ? 'website' : 'article';

  return(
    <Helmet>
      <meta property="og:title" content={title || blogTitle} />
      <meta property="og:description" content={description || blogDescription} />

      <meta property="og:url" content={blogUrl} />
      <meta property="og:type" content={type} />
      <meta property="og:site_name" content={blogTitle} />
      <meta property="og:image" content={blogImageUrl} />
      <meta property="fb:app_id" content={facebookAppId} />
      <meta name="twitter:card" content="summary" />
      <meta name="twitter:site" content={`@${blogAuthorTwitterUserName}`} />
    </Helmet>
  )
}

いろいろあるプロパティは下記の通り

プロパティ名 説明
og:title ページのタイトル。SNS共有時は、headのtitleタグよりも優先して使われます。
og:description ページの説明。
og:url ページのURL。
og:type ページの属性、だいたいwebsitearticleを指定します。詳細はココ参照
og:site_name Webサイト名。
og:image ページのイメージ画像
fb:app_id FacebookのアプリID。FacebookでOGPを表示させる際に必須。アプリIDの取り方はFacebookのOGP設定に必要なfb:app IDの取得方法参照。
twitter:card OGPのレイアウトのタイプ。詳細は【2018年版】Twitterカードとは?使い方と設定方法まとめ参照。
twitter:site Twitterのユーザ名。

OGPタグ呼び出し

こんどは作ったOgpタグを呼び出す側の実装です。 Gatsby製ブログではトップページとブログ議事ページの2カ所で呼び出します。

ブログトップページでの呼び出し

src/layouts/index.js
全体のテンプレートなのでURLがブログトップページの時のみOGPタグを呼び出します。

<Ogp isRoot={isRoot} />

ブログ記事ページでの呼び出し

src/templates/blog-post.js
<Ogp isRoot={isRoot} />
  isRoot={false}
  title={`${post.frontmatter.title} | ${siteTitle}`}
  description={sumarrize(post.html)}/>

4行目のsumarrizeメソッドではブログ記事(HTML形式)からstriptagsというライブラリを使ってテキストを抽出し、冒頭120文字を1行にして返すようにしています。

function sumarrize(html) {
  const postContent = striptags(html).replace(/\r?\n/g, '').trim();
  return postContent.length <= 120
    ? postContent
    : postContent.slice(0, 120) + '...';
}

striptagsは非常に便利なライブラリですが、1点だけ注意点があって、最新バージョンの3系(2018/9/16現在)はGatsbyビルド時にエラーになるため2系を使用してください。Gatsbyではビルド時にUglifyjsを使用しているためES6のコードをコンパイルできません。


これでTwitterなどでシェアするとイメージ画像とタイトル、記事概要を表示してくれるようになります。 つぶやきサンプル

開発中に下記サイトで実際にどんな感じになるかを確認できます。

まとめ

今回はReactアプリでSNSシェアボタンや自分のSNSへのリンクを設置し、さらにOGPタグを設置して Twitterなどでのシェアをより効果的にする方法をメモに残しました。 Reactだと、かなり簡単に実現できるし、グっと今時のWebサイトっぽくなるので是非みなさんも試してみてください。

参考