Next.jsでどうしてもReact Helmetを使いたい場合の覚書

Next.jsでOGPなどのmetaタグを取り扱う場合、next/headを使うのが基本です。が、別のアプリからマイグレした場合などで、どうしてもReact helmetからの移行が難しいケースもあります。 そんな場合の […]

広告ここから
広告ここまで

目次

    Next.jsでOGPなどのmetaタグを取り扱う場合、next/headを使うのが基本です。が、別のアプリからマイグレした場合などで、どうしてもReact helmetからの移行が難しいケースもあります。

    そんな場合の対処法について、Next.jsのExampleをベースに、自分向けにまとめました。

    React HelmetはNext.jsでそのまま動かない

    原因を深掘りしていないので不明ですが、React Helemetで書いたmetaタグがNext.jsのSSRでレンダリングされていない現象に遭遇しました。

    基本的にnext/headでReact Helmetができることはカバーできるので、そっちに切り替えるのが正攻法ではあると思います。が、Exampleでwith-react-helmetがあったことと、対応にあまり時間をかけたくなったことの2点からそのままHelmetを使うことに決定。

    _document.tsxreact-helmetのSSR処理を実行

    ExampleのコードをTypeScriptで動くようにしたものが以下です。anyで乗り切っていますが、将来的にnext/headに変える前提のため省力化したためです。

    import React from "react";
    import { Helmet } from "react-helmet";
    import Document, { Html, Head, Main, NextScript } from "next/document";
    
    export default class MyDocument extends Document<{
      helmet: any;
    }> {
      static async getInitialProps(args: any) {
        const documentProps = await super.getInitialProps(args);
        return { ...documentProps, helmet: Helmet.renderStatic() };
      }
      // should render on <html>
      get helmetHtmlAttrComponents() {
        return this.props.helmet.htmlAttributes.toComponent();
      }
    
      // should render on <body>
      get helmetBodyAttrComponents() {
        return this.props.helmet.bodyAttributes.toComponent();
      }
    
      // should render on <head>
      get helmetHeadComponents() {
        return Object.keys(this.props.helmet)
          .filter((el) => el !== "htmlAttributes" && el !== "bodyAttributes")
          .map((el) => this.props.helmet[el].toComponent());
      }
    
      render() {
        return (
          <Html {...this.helmetHtmlAttrComponents}>
            <Head>{this.helmetHeadComponents}</Head>
            <body {...this.helmetBodyAttrComponents}>
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
    
    

    参考

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark