Shopifyの埋め込みアプリにメニューをつける方法

こんにちは、mashabow です。LINE で CRM を実現する Shopify アプリ「ソーシャルPLUS」の、フロントエンド開発を担当しています。

アプリに機能が増えてくると、埋め込みアプリ(マーチャントの方に触っていただく設定画面)にメニューをつけたくなりますよね? 項目をクリックしたら画面が切り替わる、タブのようなものです。

赤枠の部分がメニューです

今回は、このメニューを埋め込みアプリにつける方法をご紹介します。

実装方法は3種類

結論から言うと、B. の NavigatonMenu を使う方法がおすすめですが、A、B、C とそれぞれ順番に説明していきます。

A. 埋め込みアプリの設定画面からメニューを設定する

設定方法

参考リンク

 

Shopify Partners から、アプリ設定 > (自分のアプリ名) > アプリ設定 のページを開いて、「埋め込み式アプリ」の項目の [管理する] をクリックします。

赤枠のボタンです

埋め込み式アプリの設定ページが開くので、メニューの [設定する] をクリック。

↑ここです

すると、メニューバーの設定ページが開くので、ここで設定していきます。

シンプルな設定画面

ストアの管理画面からアプリを開いてみると、アプリ名の下にメニューが表示されていることがわかります。(↓の画像)

なお、ここで設定したメニューは、埋め込みアプリ側(iframe の中)ではなく、Shopify Admin 側(iframe の外)に表示されることに注意してください。埋め込みアプリの内容を下にスクロールしても、メニューの位置は固定されたままになります。

メニューは 赤枠(Embedded App)の外側に表示されます

日本語メニューが追加できない問題

…が、困ったことに、この画面からは日本語のメニュー項目は追加することができません

おこられます

Shopify のフォーラムでも、この件で困っている方を見かけました。

埋め込みアプリのメニュー項目名の設定を日本語でできない。 – Shopify Community

追加できないといっても、どうやらクライアントサイドのバリデーションで引っかかっているだけのようです。ということで、[保存] ボタンをクリックしたときのリクエストを元に、自分で API を叩けば保存することができます。

res = await fetch('https://partners.shopify.com/1111111/api/graphql', {
  method: 'POST',
  headers: {
    'content-type': 'application/json',
    'X-CSRF-Token': '...',
  },
  body: JSON.stringify({
    operationName: 'EditExtension',
    variables: {
      input: {
        type: 'APP_NAV_ITEM',
        appId: '2222222',
        context: 'primary_navigation',
        config: JSON.stringify({
          children: [
            // ここにメニューが入る
            { label: 'ほげほげ', path: 'hogehoge' },
            { label: 'ふがふが', path: 'fugafuga' },
            { label: 'ぴよぴよ', path: 'piyopiyo' },
          ],
        }),
        id: '3333333',
      },
    },
    query: 'mutation EditExtension($input: UpdateExtensionInput!) {\n  extensionUpdate(input: $input) {\n    extension {\n      id\n      __typename\n    }\n    userErrors {\n      field\n      message\n      __typename\n    }\n    __typename\n  }\n}\n',
  }),
});

実行後、ページをリロードするとこんな感じになります。

ぴよぴよも追加してみました

ストアの管理画面からアプリを開いてみても正しく表示されています。

日本語でも設定ができました

この方法の問題点

設定自体はかんたんにできるのですが、以下の問題点が気になります。

  • 動的にメニューを変更する方法がない。したがって、多言語化もできない
  • アプリの設定画面から手動で設定する必要があるので、コード管理ができない
  • hack しないと日本語でメニューを設定できない

B. App Bridge の NavigationMenu を使う

App Bridge の NavigationMenu を使うと、埋め込みアプリから動的にメニューを設定することができます 。

以下は、Next.js 製の埋め込みアプリからメニューを設定するカスタムフックの例です。

import { useAppBridge } from '@shopify/app-bridge-react';
import { NavigationMenu, AppLink } from '@shopify/app-bridge/actions';
import { useRouter } from 'next/router';
import { useEffect } from 'react';

export const useNavigationMenu = (): void => {
  const app = useAppBridge();
  const router = useRouter();

  useEffect(() => {
    const items = [
      { label: 'ほげほげ', destination: 'hogehoge' },
      { label: 'ふがふが', destination: 'fugafuga' },
      { label: 'ぴよぴよ', destination: 'piyopiyo' },
    ].map((item) => AppLink.create(app, item));

    // 複数回 create() しても問題なく動く様子
    NavigationMenu.create(app, {
      items,
      // 現在のページのパスに完全一致する項目を active にする
      // このあたりのロジックはお好みで
      active: items.find(({ destination }) => destination === router.pathname),
    });
  }, [app, router.pathname]);
};

表示の位置やスタイル、クリック時の挙動は、A. で設定したメニューとまったく同じです。

まったく同じ

もし、A. のメニューが設定済みの場合、この NavigationMenu で上書きされます。items を空配列 [] にすると、メニューの領域は確保されず、何も表示されません。

というわけで、この NavigationMenu を使うと、A. の問題点がすべて解決することになります

気になる点

App Bridge のドキュメントはスクリーンショットが無いので、若干分かりにくいですね。App Bridge は Shopify Admin の中でないと動かないので、ローカルでさっと動作確認することもできません。この NavigationMenu の存在にも、最初は気づいていませんでした。

C. 自作のメニューを埋め込みアプリ内に追加する

メニューのコンポーネントを自作し、埋め込みアプリ内(iframe の中)に表示させる方法です。ちなみに、B. の方法を知らなかった開発段階では、Polaris の Tabs コンポーネント を使ってメニューを自作していました。

自作コンポーネントでの表示例

しかし Polaris の Tabs コンポーネントの問題なのか、たまにレイアウトが崩れたり、Cannot read property 'panelID' of undefined というエラーでクラッシュしたりと、不安定な挙動に悩まされていました。

こんな感じで崩れたりしました

ちなみに Polaris の Tabs コンポーネントは、B. の NavigationMenu(下図)と比較すると、若干スタイルが異なります。

選択した際のバーの長さとか

自作メニューによる実装は、他のアプリでもよく見かけます。B. の NavigationMenu の知名度がいまいち低いのが、要因なのかもしれません。

まとめ

以上、埋め込みアプリのメニューについて説明しました。これから開発される方には B. の NavigationMenu がおすすめです。

ちなみに App Bridge には、NavigationMenu以外にもいろいろな機能があります。9月に参加させていただいた「Shopify 開発者向け配信」の中でもご紹介しましたので、アプリ開発に興味がある方はぜひご覧ください!