カグラボ

<!--何かとごちゃごちゃしがちな思考を整理するブログ-->

OGP画像を表示できるようにGatsbyを弄った。

2022/02/03

概要

TwitterやSlackなどで記事をシェアした際にOGP画像がないため、見た目がショボショボで辛かったので、急遽デフォルトで表示されるOGP画像を作成してGatsby側でも表示できるようにしてみました。

諸々の表示確認しているときにlocalhostvercelのpreview環境だと正常に表示されなかったりしてハマったので経緯などを備忘録として残しておきます。

完成図

Twitterだとこんな感じに表示されるようになりました。

※TOP(Blog Archives Page)だと「All Posts」と表示されるのイマイチ感あるが、とりあえずデフォのまま放置してます

やったこと

こちらのPRの通り・・・というと若干乱暴なので補足。

  1. OGP画像の作成
  2. gatsby-config.js への siteMetaData の定義
  3. /src/components/seo.js 内で graphqlから siteMetaData の値を呼び出して react-helmet でSeoComponentにセットする

1. OGP画像の作成

Affinity Phoroを活用して適当に作成した

オワリッ!

2. gatsby-config.jsにsiteMetaDataを定義

WordPressをHeadlessCMSとして利用したGatsbyのスターターテーマをベースに使っているため、元々の設定されていたMeta情報はWordPress側で設定された各種情報をgraphql経由で取得して利用する形だった。

しかし、このブロクの運用は

  • そもそもWP自体は別ドメイン (Gatsby側のURLと異なるので絶対パスをgraphqlで取得しても…って感じ)
  • 記事だけHeadlessCMSとして抽出したい (PC以外でも突発的に記事をリライトしたいし、画像をいい感じに放り込むだけで記事を書けるようにしたいというニーズを満たすためだけのもの)

という感じなので、gatsby-config.jsにMeta情報を書き出すことにしました。

3. /src/components/seo.jsの調整

次に、gatsby-config.js で指定した siteMetaData と、下記のクエリを叩いて取得した値を組み合わせてSEOコンポーネントにセットしました。

    
    graphql`
      query {
        file(relativePath: {eq: "default_image.png"}) {
          id
          childImageSharp {
            gatsbyImageData
          }
        }
      }
    `
    

最初は下記のようにfixedで記載してたんですが、非推奨とのことでwarningが表示されたため、 gatsbyImageData で取得するように変更しています。

    
    graphql`
      query {
        file(relativePath: {eq: "default_image.png"}) {
          id
          childImageSharp {
            fixed {
              src
              srcSet
              originalName
            }
          }
        }
      }
    `
    // warn [gatsby-transformer-sharp] The "fixed" and "fluid" resolvers are now deprecated.
    // Switch to "gatsby-plugin-image" for better performance and a simpler API.

    

ハマったポイント

localhostおよび、vercelのpreview環境でwindow.locationが取得できない

gatsbyでは@react/routerではなく、@reach/routerを内部で利用しているため、useLocation()で取得したoriignを元に各環境ごとに ${siteUrl}${ogpImage}の形で動的にogp画像を呼び出せるようにしようとした

    
    import { useLocation } from "@reach/router";

    const location = useLocation();
    const siteUrl = location.origin;
    const ogpImage = file.childImageSharp.gatsbyImageData.images.fallback.src;
    const images = ${siteUrl}${ogpImage};
    

が、

gatsby developで開発していたlocalhostの場合は、"localhost/static/**********/*****/ogp_images.png" で取得することができたが、vercelのpreview環境やPRD環境だと location.originundefinedになってしまい "undefined/static/**********/*****/ogp_images.png" という形になってしまった。

ogp画像は絶対パスで指定しないとダメなため、色々調べてみたがlocation.origin が利用できるのは、window.location にアクセスできるブラウザレンダリング時のみでSSR時はアクセスできないため undefined になる模様。

Gatsby公式でも「SSR時は siteMetaData から呼び出すようにしてね」と記載されていたので、それに準拠することした。

やりたい事は達成できていたので、ひとまずはPRD環境以外でogp画像を確認することは諦める形としました。

※こちらについて、うまい対処がわかる人いれば教えてください