gatsby-browser.jsについて


基本的な内容ですが、これまであまり深くドキュメントを読み込んでいなかったため、まとめてみました。
gatsby-browser.jsの使い方をしればrootの設定などいろいろなことができます。
基本的にはドキュメントを読めばOKです。
初心者向けです。
Gatsby Browser API

gatsby-browser.jsとは?

create-react-appでいうところのApp.js,Next.jsでいうところの_app.jsと言えばイメージしやすいでしょうか?rootへの設定、グローバルに読み込ませたい設定などをすることができます。
具体的な設定については冒頭のドキュメントをご覧ください。

wrapRootElement

まず、BrowserAPIの中でよく設定するRootを扱うwrapRootElementについて紹介したいと思います。
WrapRootElement

これを設定するとpage要素をラップしてくれるようになります。
これはProviderなどを設定する際に使用します。公式ではreduxの例が紹介されています。
elementとは ReactNode要素を指します。

const React = require("react")
const { Provider } = require("react-redux")

const createStore = require("./src/state/createStore")
const store = createStore()

exports.wrapRootElement = ({ element }) => {
  return (
    <Provider store={store}>
      {element}
    </Provider>
  )
}


以下はEmotionでThemeProviderを設定した例になります。

import React from 'react';
import { ThemeProvider } from 'emotion-theming';


import { Layout } from './src/components/layout';
//colorなどの共通の設定のファイルをインポート
import { theme } from './src/theme';


export const wrapRootElement = ({ element }) => {
  return (
    <ThemeProvider theme={theme}>
      <Layout>{element}</Layout>
    </ThemeProvider>
  );
};


useContextでダークテーマの状態管理する例なども紹介されていました。
Using React Context API with Gatsby

gatsby-ssr.jsにも同様のAPIが用意されていて、このAPIを使用する際には同じく設定する必要があります

//gatsby-ssr.js
export { wrapRootElement } from './gatsby-browser';


Layoutを設定する

上記のEmotionの例で紹介しましたが、Layoutなどの共通となるUI設定などを使用することもできます。これを設定するとsrc/pages配下を全てLayoutでラップすることができます。

layout.tsxを作成

import React from 'react';

import './index.css';
import { Header } from '../templates/Header';
import { Footer } from '../templates/Footer';

type Props = {
  children: any;
};

export const Layout: React.FC<Props> = ({ children }) => {
  return (
    <>
      <Header />
      <div
        style={{
          margin: `0 auto`,
          maxWidth: 960,
          padding: `0 1.0875rem 1.45rem`,
        }}
      >
        <main>{children}</main>
      </div>
      <Footer />
    </>
  );
};


gatsby-browser.jsでラップする

import React from 'react';
import { Layout } from './src/components/layout';

export const wrapPageElement = ({ element }) => {
  return <Layout>{element}</Layout>;
};


上記のようにLayoutのようなUI要素だけをラップする際にはwrapPageElementを使用すると良いでしょう。
これによって以下のようにラップしなくてもLayoutの設定をすることができます。

import * as React from 'react';

//<Layout>で囲わなくてもスタイルが適用される
const Welcome = () => {
  return (
    <>
      <h1>Welcome</h1>
    </>
  );
};

export default Welcome;


まとめ

ドキュメントを読めばわかる内容ではありますが、rootをいじくる際に戸惑ったのでまとめてみました。状態管理などを行う際によく使うと思うので参考にしてみてください。