shopify-app-nodeで作ったNext.jsアプリから`getInitialProps`を取り除く

Shopify App CLIおよびshopify-app-nodeを使うことで、Next.jsでのShopifyアプリ開発をスムーズにはじめることができます。ただし、Next.jsが推奨する書き方よりも少し古い場合があります。

例えば、テンプレートにはgetInitialPropsを使ってURLのクエリストリングからデータを取得する処理があります。しかしNext.js9.4以降では、この関数の利用はあまり推奨されていません。

ということで、この関数を使わずにデータを取得する方法を紹介します。

Before

import { AppProvider } from "@shopify/polaris";
import { Provider } from "@shopify/app-bridge-react";
import "@shopify/polaris/dist/styles.css";
import translations from "@shopify/polaris/locales/en.json";

class MyApp extends App {
  render() {
    const { Component, pageProps, host } = this.props;
    return (
      <AppProvider i18n={translations}>
        <Provider
          config={{
            apiKey: API_KEY,
            host: host,
            forceRedirect: true,
          }}
        >
          <MyProvider Component={Component} {...pageProps} />
        </Provider>
      </AppProvider>
    );
  }
}

MyApp.getInitialProps = async ({ ctx }) => {
  return {
    host: ctx.query.host,
  };
};

export default MyApp;

After

URLのクエリストストリングを取得したい場合、Next.jsのuseRouterを使うのが無難です。これを使うことで、以下のように書き換えることができます。

import { AppProvider } from "@shopify/polaris";
import { Provider } from "@shopify/app-bridge-react";
import { useRouter } from 'next/router'
import "@shopify/polaris/dist/styles.css";
import translations from "@shopify/polaris/locales/en.json";

function MyApp({ Component, pageProps, ...props }: AppProps) {
  const { query: { host } } = useRouter()

  return (
    <AppProvider i18n={translations}>
      <Provider
        config={{
          apiKey: process.env.NEXT_PUBLIC_SHOPIFY_API_KEY as string,
          host,
          forceRedirect: true
        }}>
        <Component {...pageProps} />
      </Provider>
    </AppProvider>
  )
}

export default MyApp

TypeScriptを使う場合のもう一手間

useRouterで取得した場合、型定義がstring | string[] | undefinedのようなUnion型できます。そのため、以下のような処理をいれてstringとしてProviderに渡す必要があります。

  const {
    query
  } = useRouter()
  const host = Array.isArray(query.host) ? query.host[0] :query.host || ''

Comment