2021-12-04

【Gatsby.js】Twitterカード用の画像URLの取得どうやる?

MarkdownのFrontmatterに書かれた画像URLのとり方がわからない。しかしog:imageタグは画像URLの指定が必要。どうすればよい?

Article Image

Twitterカードに画像を設定する

picture 1

Twitterカードに画像を設定する場合メタタグにog:image(もしくはtwitter:image)というデータを作ると思う。

ここには画像URLを入れる必要がある。

BLOGの場合アイキャッチに設定されているデータを入れることが殆どだろう。

今回はGatsby.jsにてこの画像用のURLを取得したい。

余談:URLは絶対パス

今回のテーマとは関係ないがここでog:image画像URLは必ず絶対パスで書く必要があるので予め注意する。

例えばわたしのWEBサイトならhttps://www.ultra-noob.com/img/img.png

./などの相対パスにしないようにしよう。

Frontmatterから画像URLが取れない問題

picture 2

私のBLOGのみならず多くのGatsbyを使ったBLOGでFrontmatterにタイトル画像のURLが入っていると思う。

例えば私のMarkdownの例だと次のようなFrontmatterになっている。

title: タイトル
date: '2021-12-4T19:54:25'
featuredimage: img/title.png

タイトル画像はfeaturedimageという項目に設定している。

デベロッパーツールを使って実際に生成されたWEBページの画像からURLを調査すると次のように意味不明なコードに変換されている。

/static/d30ab0daa94ec6e1911ec83875712309/60e69/title.png

知らない人もいるかもしれないがGatsby.jsはbuild時に指定された画像を再処理し、いい感じになるよう調整してくれている。

これがディレクトリ直下のURLではなく違った画像へのリンクとなる原因。

結果Twitter用の画像URLを埋め込もうと思ったときに「あれ、URLどうすればいいんだ?」という疑問へつながる。

URLの取得方法

結論から言えば私は次のコードで画像URLを取得している。

const imagePath = data.markdownRemark.frontmatter.featuredimage?.childImageSharp?.gatsbyImageData?.images?.fallback?.src || ""

解説

frontmatterの中のfeaturedimageは私のmdファイルに記述されたYAMLのデータ名なので各自によって違うはず。

ただ、この画像はchildImageSharpというプラグインで処理されるため.childImageSharpで繋いでその中のデータ項目にURLが入っている箇所がある。

もしよくわからない場合はblog記事のページのコードでconsole.logなどを使ってfrontmatterの中身がどうなっているかを確認すれば良い。

おまけ:「?.」ってなに?

上のコードの?.を初めてみる人もちらほらいるかと思う。

これはJSに比較的新しく入っているオプショナルチェイニング演算子(またはオプショナルチェーン演算子)と呼ばれるもの。

オプショナルチェーン (?.) - JavaScript | MDN

例えば上の例を少し簡略化して

const imagePath = data.markdownRemark.frontmatter.featuredimage?.childImageSharp

というコードを書いたときにdata.markdownRemark.frontmatterは存在するのだけれど、この下に.featuredimageというデータ項目がもしも存在しなかった場合、そもそも存在しないfeaturedimageの更に下にあるchildImageSharpを取ろうとすると 「エラー」でプログラムが停止してしまう。

解釈が少し難しいかもしれないが、つまり「存在しないキー」を調べるだけならundefinedで問題ないが 「存在しないキーの中にある更に深いキー」を取得しようとするとエラーで停止 するということを防止するコードだ。

というわけで、上の例では 「画像のURLが指定されていなかった場合でもエラーではなく空白にする」 という処理になっているわけである。

おまけ:カードの確認

ツイッターのカードが生成できているかどうかは次のURLで行える。わざわざ一度ツイートする必要はない。

Card Validator | Twitter Developers

このサイトにBLOGの記事URLを入れてPreviewしてみよう。

最後に

私の場合これでimagePathというデータにURLが入ってくるので、あとはヘッダ側のコードに渡してやるだけでよい。

ただ、この方法はあくまでFrontmatterに記述されている画像URLを取るものであり、Markdown内に直接書かれている画像を取るものではないので注意が必要。


この記事のタグ

この記事をシェア


謎の技術研究部 (謎技研)