Gatsby で作成したブログに react-helmet-async で meta 情報を埋め込む

2021-11-18

Feature image for this page

こぷらです。

Gatsby で作成した Web ページに meta 情報を埋め込むために react-helmet-async を使ってみました。 もともと react-helmet を使っていたのですが、年単位でメンテナンスされていなかったのが気になったので変えてみました。 界隈的にも react-helmet-async を使うほうがメジャーっぽいです。

react-helmet vs react-helmet-async

react-helmet vs react-helmet-async

変更自体はとても簡単にできます。 ただ実際にやってみると、Gatsby のビルド方法について学ぶ部分が多いと思います。 それでは早速やってみましょう。

目次

パッケージインストール

まずは必要なパッケージのインストールです。

yarn add react-helmet-async gatsby-plugin-react-helmet-async

プラグインのドキュメントで react および react-dom の最小バージョンが 16.6 とあるので、それ以下のバージョンを使っているならアップデートをしておきましょう。

react-helmet-async requires your react and react-dom to be at least 16.6.0. If they’re older than that, you’ll need to upgrade them: gatsby-plugin-react-helmet-async | https://www.gatsbyjs.com/plugins/gatsby-plugin-react-helmet-async/?=helmet

yarn add react@^16.6.0 react-dom@^16.6.0

ついでに不要になった react-helmet 関連のモジュールをアンインストールします。

yarn remove react-helmet gatsby-plugin-react-helmet

使い方

Helmet コンポーネントの置換

各種タグの追加は react-helmet と同じです。 そのため、まず Helmet コンポーネントのインポート先だけを変えます

// import { Helmet } from 'react-helmet'
import { Helmet } from 'react-helmet-async'

また、gatsby プラグインも変更しておきます。

gatsby-config.js
module.exports = {
  plugins: [
    // `gatsby-plugin-react-helmet`, 削除
    `gatsby-plugin-react-helmet-async`,  // 追加
  ]
}

HelmetProvider でラップする

そして react-helmet-async を使うためには、Web サイトのルート要素を HelmetProvider コンポーネントでラップする必要があります。 ドキュメント では以下のように紹介されています。

import React from 'react';
import ReactDOM from 'react-dom';
import { Helmet, HelmetProvider } from 'react-helmet-async';

const app = (
  <HelmetProvider>
    <App>
      <Helmet>
        <title>Hello World</title>
        <link rel="canonical" href="https://www.tacobell.com/" />
      </Helmet>
      <h1>Hello World</h1>
    </App>
  </HelmetProvider>
);

ReactDOM.hydrate(
  app,
  document.getElementById(‘app’)
);

Gatsby を使っている場合、ここでちょっと苦戦しました。 というのも、ルート要素を構成するスクリプトがどこにあるかわからなかったからです。 Gatsby のドキュメントを探してみたところ、こんなページが見つかりました。

このページでは、Gatsby がビルド時に HTML ファイルへ変更を加えるための API を解説しています。 その中の wrapRootElement API が、名前の通りルート要素を別の要素でラップするためのもので、まさに今回求めていた機能でした。 HelmetProvider をラップするために、この API を使ってみます。

wrapRootElement API を使って HelmetProvider をラップする

wrapRootElement API を呼び出すためには、プロジェクトルートに gatsby-ssr.js ファイルを作成する必要があります。 私のサイトは TypeScript で構築しているので、gatsby-ssr.tsx を作成しました。 ファイルの中身は以下のとおりです。

gatsby-ssr.tsx
import * as React from 'react'
import type { GatsbySSR } from 'gatsby'
import { HelmetProvider } from 'react-helmet-async'

export const wrapRootElement: GatsbySSR['wrapRootElement'] = ({ element }) => {
  return <HelmetProvider>{element}</HelmetProvider>
}

NamedExport で wrapRootElement API を定義し、<HelmetProvider> でラップした RootElement を返しています。 これでサイトを立ち上げると、無事に Helmet 要素が追加されていることが確認できるはずです。

ちなみに、ドキュメント上では以下のように Gatsby Browser API と同時に使うことを推奨しているので、それに従って gatsby-browser.tsx も変更しておきましょう。

Note: There is an equivalent hook in Gatsby’s Browser API. It is recommended to use both APIs together. Gatsby Server Rendering APIs | https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/

gatsby-browser.tsx
import * as React from 'react'
import { GatsbyBrowser } from 'gatsby'
import { HelmetProvider } from 'react-helmet-async'

export const wrapRootElement: GatsbyBrowser['wrapRootElement'] = ({
  element,
}) => {
  return <HelmetProvider>{element}</HelmetProvider>
}

ちなみに、Gatsby SSR API はビルド時に、Gatsby Browser API はブラウザでのレンダリング時に呼ばれます。 この辺の仕様については後日別記事でまとめようと思います。

まとめ

今回は Gatsby で react-helmet-async を使う方法を紹介しました。 ちょっと苦戦しましたが、便利な API が提供されていたため、なんとか実装できました。

実装できただけでなく、 Gatsby SSR API を使うことで HTML ファイルに任意の変更を加えられることを知れたのが一番の収穫でした。 他にも応用できそうなので、Gatsby の開発で困っている人は、まず API を確認してみてはいかがでしょうか。

それでは。


Profile picture

Written by Coppla

職業:ソフトウェアエンジニア - 会社では精密機械の制御系ソフトウェアの開発を、プライベートで Web アプリ制作の勉強をしています。趣味は旅行と美味しいものを食べること

Categories

© 2022 Coppla, Built with Gatsby