🌉

【Shopify.dev和訳】Apps/Dev tools/App Bridge/Actions②

2021/09/10に公開約46,400字

この記事について

この記事は、Apps/Developer tools/App Bridge/Actionsの記事を和訳したものです。

記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

App Bridge/Actions(続き)

この記事は、こちらの和訳記事の続きになります。

Menu

App Bridge の Menu アクションを使用して、ダイナミックなナビゲーションを作成する方法について説明します。

このセクションでは

  • Channel Menu - App Bridge を使用して、組み込みの販売チャネルアプリのサイドバーメニューを変更する方法について説明します。

  • Navigation Menu - App Bridge を使用して、組み込みアプリのナビゲーションメニューを変更する方法について説明します。

Channel Menu

ChannelMenuアクションは、デスクトップの Shopify 管理画面のサイドバーに、ナビゲーションメニューを作成することができます。Shopify モバイルでは、メニューはNavigationMenuのように、ドロップダウンで表示されます。

設定方法

アプリを作成して、@shopify/app-bridge/actionsからChannelMenuモジュールをインポートしてください。このガイドの例では、@shopify/app-bridgeのサンプルアプリを参照しています。

import createApp from "@shopify/app-bridge"
import { ChannelMenu, AppLink } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
})

任意の数のAppLinkインスタンスを作成して、ChannelMenuに渡します。

const itemsLink = AppLink.create(app, {
  label: "Items",
  destination: "/items",
})

const settingsLink = AppLink.create(app, {
  label: "Settings",
  destination: "/settings",
})

// アクティブリンクのないChannelMenuを作成する

const channelMenu = ChannelMenu.create(app, {
  items: [itemsLink, settingsLink],
})

// または、設定リンクをアクティブにしたChannelMenuを作成します。

const channelMenu = ChannelMenu.create(app, {
  items: [itemsLink, settingsLink],
  active: settingsLink,
})

アクティブなナビ項目を設定する

メニューのアクティブな状態を更新するには、setメソッドを使ってactiveオプションへのリンクを渡します。

channelMenu.set({ active: settingsLink })

アクティブなナビ項目をリセットする

アクティブリンクを解除するには、setメソッドでactiveオプションにundefinedを指定します。

channelMenu.set({ active: undefined })

NavigationMenuアクションを使用すると、アプリのナビゲーションメニューを作成できます。デスクトップのウェブブラウザでは、ナビゲーションメニューはアプリのタイトルの下、画面の一番上に表示されます。Shopify モバイルでは、ナビゲーションメニューはタイトルバーからドロップダウンで表示されます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからNavigationMenuモジュールをインポートしてください。このガイドの例では、@shopify/app-bridgeのサンプルアプリを参照しています。

import createApp from "@shopify/app-bridge"
import { NavigationMenu, AppLink } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
})

任意の数のAppLinkインスタンスを作成し、それをNavigationMenuに渡します。各AppLinkインスタンスは、メニュー上のリンクを表します。

const itemsLink = AppLink.create(app, {
  label: "Items",
  destination: "/items",
})

const settingsLink = AppLink.create(app, {
  label: "Settings",
  destination: "/settings",
})

// アクティブリンクのないNavigationMenuを作成する

const navigationMenu = NavigationMenu.create(app, {
  items: [itemsLink, settingsLink],
})

// または、設定リンクをアクティブにしたNavigationMenuを作成する

const navigationMenu = NavigationMenu.create(app, {
  items: [itemsLink, settingsLink],
  active: settingsLink,
})

アクティブなナビアイテムの設定

メニューのアクティブな状態を更新するには、setメソッドを使ってactiveオプションへのリンクを渡します。

navigationMenu.set({ active: settingsLink })

アクティブなナビ項目のリセット

アクティブなリンクを消去するには、setメソッドでactiveオプションとしてundefinedを渡します。

navigationMenu.set({ active: undefined })

Modal

モーダルとは、特定のアクションが実行されるまで、マーチャントがアプリの他の部分とやり取りすることを妨げるオーバーレイです。

モーダルは、マーチャントが Shopify の他の部分と対話を続ける前にアクションを取ることを要求するため、混乱を招く可能性があります。そのため、モーダルは慎重に、そして控えめに使用する必要があります。

Modalアクションセットでは、メッセージと iframe という 2 種類のモーダルを開くことができます。メッセージモーダルは、プレーンテキストコンテンツのみをサポートします。Iframe モーダルでは、モーダルのコンテンツを完全にカスタマイズすることができます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからModalモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { Modal } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

メッセージモーダルの作成

messageオプションを使って、メッセージモーダルを作成します。メッセージモーダルは、messageオプションを使って、任意の長さのプレーンテキストコンテンツをサポートします。

const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
}

const myModal = Modal.create(app, modalOptions)

iframe モーダルの作成

urlオプションを渡して iframe のモーダルを作成します。urlオプションがある場合は、messageオプションは無視されます。

絶対 URL を指定して iframe モーダルを作成する

const modalOptions = {
  title: 'My Modal',
  url 'http://example.com',
};

const myModal = Modal.create(app, modalOptions);

相対パスの iframe モーダルの作成

相対パスの iframe は、アプリのルートからの相対的な URL を設定します。

const modalOptions = {
  title: "My Modal",
  path: "/settings",
}

const myModal = Modal.create(app, modalOptions)

アプリのルート URL が https://myapp.com だった場合、上記の例では https://myapp.com/settings でモーダルを開きます。

モーダルのオープンとクローズ

OPEN アクションと CLOSE アクションをディスパッチすることで、モーダルを開いたり閉じたりします。

const modalOptions = {
  title: "My Modal",
  url: "http://example.com",
}

const myModal = Modal.create(app, modalOptions)

myModal.dispatch(Modal.Action.OPEN)

// モーダルを閉じる
myModal.dispatch(Modal.Action.CLOSE)

フッターボタンの追加

モーダルのフッターにボタンを追加することができます。すべてのモーダルは、1 つのプライマリボタンと複数のセカンダリボタンをサポートしています。ボタンの詳細については、「ボタン」を参照してください。

const okButton = Button.create(app, { label: "Ok" })
okButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})

const cancelButton = Button.create(app, { label: "Cancel" })
cancelButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})

const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
  footer: {
    button: {
      primary: okButton,
      secondary: [cancelButton],
    },
  },
}

const myModal = Modal.create(app, modalOptions)

サブスクリプション

subscribeを呼び出すことで、モーダルアクションをサブスクライブすることができます。この関数は、アクションのサブスクライブを解除するために呼び出すことができる関数を返します。

const modalOptions = {
  title: "My Modal",
  url: "http://example.com",
}

const myModal = Modal.create(app, modalOptions)

const openUnsubscribe = myModal.subscribe(Modal.Action.OPEN, () => {
  // オープンイベントで何かをする
})

const closeUnsubscribe = myModal.subscribe(Modal.Action.CLOSE, () => {
  // 閉じるイベントで何かをする
})

// アクションの登録を解除する
openUnsubscribe()
closeUnsubscribe()

App Bridge のすべてのアクションセットは、同じ subscribe API をサポートしています。モーダルフッターのボタンも、unsubscribe関数を返します。

const okButton = Button.create(app, { label: "Ok" })
const okButtonUnsubscribe = okButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})

okButtonUnsubscribe()

すべての人の登録解除

unsubscribe を呼び出すことで、モーダルとその子(ボタンを含む)のすべてのサブスクライブを解除することができます。

const okButton = Button.create(app, { label: "Ok" })
okButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})
const cancelButton = Button.create(app, { label: "Cancel" })
cancelButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})
const modalOptions = {
  title: "My Modal",
  url: "http://example.com",
  footer: {
    button: {
      primary: okButton,
      secondary: [cancelButton],
    },
  },
}

const myModal = Modal.create(app, modalOptions)

myModal.subscribe(Modal.Action.OPEN, () => {
  // オープンイベントで何かをする
})

myModal.subscribe(Modal.Action.CLOSE, () => {
  // 閉じるイベントで何かをする
})

// モーダルのオープンとクローズのアクションを解除する
// okButton と cancelButton のクリックアクションのサブスクライブを解除する
myModal.unsubscribe()

モーダルアクションからのみ登録解除する

unsubscribefalse を指定して呼び出すと、子のサブスクリプションを残したままモーダルのサブスクリプションだけを削除することができます。例えば、モーダルのサブスクライブは解除するが、ボタンのリスナーは残しておき、別のモーダルでボタンを再利用できるようにしたい場合などです。

const okButton = Button.create(app, { label: "Ok" })
okButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})
const cancelButton = Button.create(app, { label: "Cancel" })
cancelButton.subscribe(Button.Action.CLICK, () => {
  // クリックアクションで何かをする
})

const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
  fotter: {
    button: {
      primary: okButton,
      secondary: [cancelButton],
    },
  },
}

const myModal = Modal.create(app, modalOptions)

// モーダルの開閉アクションからのみ登録解除する
myModal.unsubscribe(false)

// 上のボタンは、新しいモーダルで再利用できます。
// それらのサブスクリプションはそのまま残されます

const newModalOptions = {
  title: "Confirm",
  message: "Are you sure?",
  footer: {
    button: {
      primary: okButton,
      secondary: [cancelButton],
    },
  },
}

const confirmModal = Modal.create(app, newModalOptions)

オプションの更新

既存のモーダルのオプションを更新するために、部分的なモーダルのオプションで set メソッドを呼び出すことができます。これにより、モーダルのupdateアクションが自動的に開始され、与えられたオプションが既存のオプションにマージされます。

const modalOptions = {
  title: "私のモーダル",
  url: "http://example.com",
}

const myModal = Modal.create(app, modalOptions)

myModal.set({ title: "My new title" })

フッターボタンの更新

モーダルのフッターに付いているボタンを更新することができます。モーダルのフッターボタンが更新されると、モーダルのupdateアクションが自動的に行われます。

const okButton = Button.create(app, { label: "Ok" })
const cancelButton = Button.create(app, { label: "Cancel" })
const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
  footer: {
    button: {
      primary: okButton,
      secondary: [cancelButton],
    },
  },
}

const myModal = Modal.create(app, modalOptions)
myModal.dispatch(Modal.Action.OPEN)

okButton.set({ label: "Good to go!" })

モーダルサイズの設定

デフォルトでは、モーダルのサイズはSmallに固定されています。別の Modal.Size 値を渡すことで、モーダルのサイズをカスタマイズすることができます。

const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
  size: Modal.Size.Large,
}

const myModal = Modal.create(app, modalOptions)
myModal.dispatch(Modal.Action.OPEN)

Modal.SizeにはSmallMediumLargeの 3 つの値があります。

モーダルのサイズを自動的に設定する

setupModalAutoSizingユーティリティを使用すると、iframe モーダルの高さをページコンテンツに合わせて更新することができます。

メインアプリで、iframe モーダルを開きます。

import createApp from "@shopify/app-bridge"
import { Modal } from "@shopify/app-bridge/actions"
import { setupModalAutoSizing } from "@shopify/app-bridge-utils"

const app = createApp({
  apiKey: "12345",
})

const modalOptions = {
  title: "My Modal",
  path: "/modal",
}

const myModal = Modal.create(app, modalOptions)
myModal.dispatch(Modal.Action.OPEN)

モーダルページの中で、setupModalAutoSizingユーティリティをインポートして、自動サイズ調整を有効にします。

import createApp from "@shopify/app-bridge"
import { setupModalAutoSizing } from "@shopify/app-bridge-utils"
const app = createApp({
  apiKey: "12345",
})
setupModalAutoSizing(app)

モーダルページの <body> 要素に heightmarginpadding スタイルを設定することは避けてください。回避策としては、代わりにラッパー要素にこれらのスタイルを設定してください。

Shopify Polaris を使用している場合、デフォルトで <body> 要素に height: 100% が適用されることに注意してください。モーダルページでこのスタイルをオーバーライドする必要があります。

親ページとのコミュニケーション

モーダルが親ページと通信できると便利な場合があります。DATAアクションを使用すると、iframe モーダルとその親アプリの間でメッセージを送信できます。

モーダルからデータを送信するには、モーダルから Modal.Action.DATA アクションをディスパッチします。

import createApp from "@shopify/app-bridge"
import { Modal } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
})

const payload = {
  message: "Hi this is modal!",
}
app.dispatch(Modal.data(payload))

アプリでは、Modal.Action.DATAをサブスクライブします。

import createApp from "@shopify/app-bridge"
import { Modal } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
})

app.subscribe(Modal.Action.DATA, (action) => {
  console.log("Received message from modal:", action)
})

アプリからモーダルにデータを送信するには、手順を逆に行います。モーダルで Modal.Action.DATA をサブスクライブし、アプリから Modal.Action.DATA アクションをディスパッチします。

Navigation

Shopify App Bridge には、ナビゲーションに関連する 2 つのアクションセットがあります。

どちらのアクションセットも、トップレベルのブラウザの URL にアクセスすることができます。

Historyアクションセットでは、JavaScript の履歴 API を使用して、ナビゲートせずにトップレベルのブラウザ URL を変更することができます。Historyアクションセットを使用して、ブラウザのトップレベルの URL をアプリに合わせて更新します。

Redirectアクションセットを使用すると、トップレベルのブラウザ URL を変更できます。リダイレクトアクションセットを使用して、アプリ内をナビゲートしたり、マーチャントを Shopify 管理画面やウェブ上の別の場所にリダイレクトしたりできます。

クライアントサイドルーティングの使用

デフォルトでは、App Bridge は iframe の URL を変更することで、ナビゲーションアイテムがクリックされた場合など、アプリの外部からの URL 変更を適用します。アプリが React Router などのクライアントサイドルーティングを使用している場合は、不要なフルページリロードを避けるために、この動作をオーバーライドする必要があります。

デフォルトの動作をオーバーライドするには、Redirect.Action.APPアクションをサブスクライブしてください。

import {Redirect} from '@shopify/app-bridge/actions';

app.subscribe(Redirect.Action.APP, function(redirectData) {)
  console.log(redirectData.path); // 例えば、'/settings' です。
});

アプリがこのアクションにサブスクライブしている場合、App Bridge は iframe の URL を変更しません。代わりに、コールバック関数にパスを渡し、そこでクライアントサイドのルーターにパスを渡すことができます。

History

Historyアクションセットでは、JavaScript History API を使用して、ナビゲートせずにブラウザのトップレベル URL を変更できます。Historyアクションセットを使用して、ブラウザのトップレベルの URL をアプリに合わせて更新します。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからHistoryモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { History } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

const history = History.create(app)

アプリの相対パスを含む新しい履歴エントリをプッシュします。

パスはアプリのオリジンからの相対パスで、プレフィックスとしてスラッシュを付ける必要があります。ヒストリー エントリを追加しても、アプリはリダイレクトされません。

// {appOrigin}/settings を履歴にプッシュします。
history.dispatch(History.Action.PUSH, "/settings")

現在の履歴エントリを、相対的なアプリのパスで置き換える

パスはアプリのオリジンからの相対パスで、先頭にスラッシュを付ける必要があります。ヒストリーエントリを置き換えても、アプリのリダイレクトは行われません。

// 現在のヒストリーの URL を {appOrigin}/settings で置き換えます。
history.dispatch(History.Action.REPLACE, "/settings")

アクションのサブスクライブ

特定のヒストリー アクション セットを通じてディスパッチされたアクションをサブスクライブすることができます。

history.subscribe(History.Action.REPLACE, (payload: History.Payload) => {
  // 履歴の置換アクションで何かをする
  console.log(`Updated the history entry to path: ${payload.path}`)
})

history.subscribe(History.Action.PUSH, (payload: History.Payload) => {
  // ヒストリープッシュアクションで何かをする
  console.log(`Added a history entry with the path: ${payload.path}`)
})

すべてのヒストリーアクションをサブスクライブする

どのアクションセットがアクションを引き起こすかに関わらず、すべてのヒストリーアクションをサブスクライブすることができます。

app.subscribe(History.Action.REPLACE, (payload: History.Payload) => {
  // 履歴の置換アクションで何かをする
  console.log(`Updated the history entry to path: ${payload.path}`)
})

app.subscribe(History.Action.PUSH, (payload: History.Payload) => {
  // ヒストリープッシュアクションで何かをする
  console.log(`Added a history entry with the path: ${payload.path}`)
})

Redirect

Redirectアクションセットは、ブラウザのトップレベルの URL を変更することができます。Redirectアクションセットを使用して、アプリ内をナビゲートしたり、マーチャントを Shopify 管理画面内やウェブ上の他の場所にリダイレクトしたりできます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからRedirectモジュールをインポートしてください。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { Redirect } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

const redirect = Redirect.create(app)

アプリの相対パスにリダイレクトする

ローカルアプリのパスにリダイレクトします。パスの前にはスラッシュをつけなければならず、アプリのオリジンからの相対パスとして扱われます。

// {appOrigin}/settings に移動します。
redirect.dispatch(Redirect.Action.APP, "/settings")

アプリの外、Shopify 管理画面の外にある絶対的な URL にリダイレクトします。

// http://example.com に移動します。
redirect.dispatch(Redirect.Action.REMOTE, "http://example.com")

新しいウィンドウで開く

newContextオプションを追加します(<a target="_blank">と同等)。

// 新しいウィンドウで http://example.com に移動
redirect.dispatch(Redirect.Action.REMOTE, {
  url: "http://example.com",
  newContext: true,
})

Shopify 管理画面で相対パスにリダイレクトする

Shopify admin の customers セクションにリダイレクトします。パスの前にスラッシュを付ける必要があります。

// {shopUrl}/admin/customers に移動します。
redirect.dispatch(Redirect.Action.ADMIN_PATH, "/customers")

// 新しいウィンドウで {shopUrl}/admin/customers に移動します。
redirect.dispatch(Redirect.Action.ADMIN_PATH, {
  path: "/customers",
  newContext: true,
})

Shopify 管理画面で指定したセクションにリダイレクトする

Shopify 管理画面の「商品」セクションにリダイレクトします。

// {shopUrl}/admin/products に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  name: Redirect.ResourceType.Product,
})

// 新しいウィンドウで {shopUrl}/admin/products に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  section: {
    name: Redirect.ResourceType.Product,
  },
  newContext: true,
})

Shopify admin で特定のリソースにリダイレクトする

Shopify 管理画面で ID123のコレクションにリダイレクトします。

// {shopUrl}/admin/collections/123 に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  name: Redirect.ResourceType.Collection,
  resource: {
    id: "123",
  },
})

Shopify 管理画面で商品を作成するためのリダイレクト

Shopify 管理画面の{shopUrl}/admin/products/newにリダイレクトします。

// {shopUrl}/admin/products/new に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  name: Redirect.ResourceType.Product,
  resource: {
    create: true,
  },
})

Shopify admin で商品のバリエーションにリダイレクトします

Shopify admin で ID '123'のコレクションにリダイレクトします。

// {shopUrl}/admin/products/123/variant/456 に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  name: Redirect.ResourceType.Product,
  resource: {
    id: "123",
    variant: {
      id: "456",
    },
  },
})

Shopify 管理画面で新しい製品バリアントを作成するためのリダイレクト

Shopify 管理画面の{shopUrl}/admin/products/123/variants/newにリダイレクトします。

// {shopUrl}/admin/products/123/variants/new に移動します。
redirect.dispatch(Redirect.Action.ADMIN_SECTION, {
  name: Redirect.ResourceType.Product,
  resource: {
    id: "123",
    variant: {
      create: true,
    },
  },
})

アクションのサブスクライブ

リダイレクトアクションセットを通じてディスパッチされたアクションをサブスクライブすることができます。

redirect.subscribe(Redirect.Action.APP, (payload: Redirect.AppPayload) => {
  // リダイレクトで何かをする
  console.log(`Navigated to ${payload.path}`)
})

すべてのリダイレクトアクションをサブスクライブ

どのアクションセットがアクションを引き起こすかに関わらず、アプリ内のすべてのリダイレクトアクションをサブスクライブすることができます。

app.subscribe(Redirect.Action.APP, (payload: Redirect.AppPayload) => {
  // リダイレクトで何かをする
  console.log(`Navigated to ${payload.path}`)
})

現在の制限事項

クエリストリクター

クエリストリームの使用はサポートされていません。すべてのクエリストリームは、リダイレクトの際にパスから削除されます。

POS

Shopify POS で動作しているときにアプリを終了したり、Shopify POS デバイスの情報を取得するためのメカニズムを提供します。

必要条件

  • ユーザーと位置情報は、Android と iOS のすべてのバージョンの Point of Sale で利用可能です。
  • デバイスデータは以下のアプリのバージョンで利用可能です。
    • Point of Sale iOS バージョン 5.36.0以上
    • Point of Sale Android バージョン 3.29.0以上
  • Close は以下のアプリのバージョンで利用できます。
    • App Bridge のバージョン 1.18.0以上が必要です。
    • Point of Sale の iOS バージョン 5.50.0以上
    • Point of Sale Android バージョン 3.43.0以上

設定方法

アプリを作成し、@shopify/app-bridge/actionsからPosモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照しています。

import createApp from "@shopify/app-bridge"
import { Pos } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

Shopify POS に組み込まれたアプリを閉じる

埋め込みアプリを閉じるために使用できる Pos オブジェクトを作成します。ユーザーが Shopify POS アプリに戻るアクションを正常に完了した後に、埋め込みアプリを閉じることがあります。

const pos = Pos.create(app)

埋め込みアプリを閉じるには、Pos オブジェクトを使用してCLOSEアクションをディスパッチします。

pos.dispatch(Pos.Action.CLOSE)

POS データの取得

POS データはステートにあり、app.getState()でアクセスできます。データを取得する方法はいくつかあります。

オプション 1:すべてのステートを取得

app.getState().then((data) => {
  const { pos } = data
})

オプション 2:pos のみを取得

app.getState('pos').then((pos) => { {pos} = data; });
});

オプション 3: pos ユーザのみ取得

app.getState("pos.user").then((user) => {})

オプション 4: pos の位置情報だけを取得する

app.getState("pos.location").then((location) => {})

オプション 5: pos デバイスのみを取得

app.getState("pos.device").then((device) => {})

ペイロード

POS ペイロード

キー タイプ 説明
user User ユーザー情報
location Location 位置情報
device Device デバイス情報

ユーザーペイロード

キー タイプ 説明
id Number ログインユーザーの ID。
firstName String ログインユーザーのファーストネームです。
lastName String ログインユーザーのラストネーム
email String ログインユーザーの電子メール名です。
accountOwner Boolean ログインユーザーがショップオーナーであるかどうかを示します。
userType String ログインユーザーのタイプです。

ロケーションペイロード

キー タイプ 説明
id Number 現在のロケーションの ID
active Boolean 現在のロケーションのステータス。
name String 現在のロケーションの名前です。
locationType String? 現在のロケーションのタイプ。
address1 String? 現在の場所の主な住所
address2 String? 住所に関連する追加情報(アパート番号、スイート番号、ユニット番号など)。
zip String? 住所の郵便番号を入力してください。
city String? 都市の名前
province String? 住所の県名または州名
countryCode String? ISO 3166-1 (alpha-2)形式の国コードです。
countryName String? 住所の国名を指定します。
phone String? 場所の電話番号

デバイス ペイロード

キー タイプ 説明
name String デバイスの名前
serialNumber String デバイス ID とアプリ ID に関連付けられたユニークな ID です。

ResourcePicker

ResourcePickerアクションセットは、マーチャントが 1 つまたは複数の製品、コレクション、または製品バリアントを見つけて選択するための検索ベースのインターフェースを提供し、選択されたリソースをアプリに返します。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからResourcePickerモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照していることに注意してください。

import createApp from "@shopify/app-bridge"
import { ResourcePicker } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

商品ピッカーの作成

const productPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
})

製品バリエーションピッカーの作成

const variantPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.ProductVariant,
})

コレクションピッカーの作成

const collectionPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Collection,
})

ピッカーの選択とキャンセル

リソースピッカーには、サブスクライブできる 2 つの主要なアクションがあります。

ResourcePicker.Action.CANCEL - ユーザーが選択をせずにリソースピッカーをキャンセルすると、App Bridge はこのアクションをディスパッチします。
ResourcePicker.Action.SELECT - ユーザーが選択を確認した後、App Bridge はこのアクションをディスパッチします。このアクションは、idselectionキーを持つObjectであるSelectPayloadを提供します。selectionキーは、選択されたすべてのリソースの配列です。

const picker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
})

picker.subscribe(ResourcePicker.Action.CANCEL, () => {
  // ピッカーがキャンセルされました
})

ピッカー.subscribe(ResourcePicker.Action.SELECT, (selectPayload) => {
  const selection = selectPayload.selection
  // `selection` で何かをする
})

オプション

initialQuery

  • デフォルト値: undefined
  • 省略可能
  • 型: string
  • note: リソースピッカーの検索バーに事前に入力します。

initialSelectionIds

  • デフォルトの値: []
  • 省略可能
  • 型: Resource[]
  • note: initialSelectionIds は、最小のリソースオブジェクトの配列を受け取ります。リソースオブジェクトには、リソース ID (GraphQL ID 形式、例: 'gid://shopify/Product/1') だけが必要です。製品リソースには、選択されたバリアントを含めることもできます。バリアントが指定されていない場合は、すべてのバリアントが選択されます。
const productWithSpecificVariantsSelected = {
  id: "gid://shopify/Product/12345",
  variants: [
    {
      id: "gid://shopify/ProductVariant/1",
    },
  ],
}

const productWithAllVariantsSelected = {
  id: "gid://shopify/Product/67890",
}

const productPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
  options: {
    initialSelectionIds: [productWithVariantsSelected, productWithAllVariantsSelected],
  },
})

actionVerb

  • デフォルト値: ResourcePicker.ActionVerb.Add
  • 省略可能
  • 型: ResourcePicker.ActionVerb (値: Add, Select)
  • note: actionVerb は、タイトルの<actionVerb> <resourceType>とリソースピッカーのプライマリアクションとして表示されます。

selectMultiple

  • デフォルト値:true
  • 省略可能
  • 型: booleanまたはnumber
  • note: 複数のアイテムを選択できるようにするかどうかを指定します。数字が指定された場合は、選択項目をその数字の最大数に制限します。数字を指定するには、バージョン 1.28.0 が必要です。

Boolean オプション

オプション デフォルト値(default) 省略可能(optional) version 注意
showHidden true ✔️ hidden は、どの販売チャネルでも公開されていない商品を指します。
showVariants true ✔️ Product リソースタイプピッカーにのみ適用されます。
showDraft true ✔️ 1.28.0 ドラフト商品を表示するかどうかを指定します。Productリソースタイプピッカーにのみ適用されます。
showArchived true ✔️ 1.28.0 アーカイブされた製品を表示するかどうかを指定します。Product リソースタイプピッカーにのみ適用されます。
showDraftBadge false ✔️ 1.28.0 ドラフト商品にドラフトバッジを表示するかどうかを指定します。showDraft prop が設定されている場合のみ動作し、Productリソースタイプピッカーにのみ適用されます。
showArchivedBadge false ✔️ 1.28.0 アーカイブされた商品に対してアーカイブされたバッジを表示するかどうかを指定します。showArchived prop が設定されている場合にのみ動作し、Productリソースタイプピッカーにのみ適用されます。

アクションのサブスクライブ

subscribeを呼び出すことで、モーダルアクションをサブスクライブすることができます。この関数は、アクションのサブスクライブを解除するために呼び出すことができる関数を返します。

const productPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
  options: {
    selectMultiple: true,
    showHidden: false,
  },
})

const selectUnsubscribe = productPicker.subscribe(ResourcePicker.Action.SELECT, ({ selection }) => {
  // `selection` で何かをする
})

const cancelUnsubscribe = productPicker.subscribe(ResourcePicker.Action.CANCEL, () => {
  // ピッカーがキャンセルされました
})

// アクションの登録解除
selectUnsubscribe()
cancelUnsubscribe()

サブスクライブ解除

unsubscribe を呼び出すことで、リソースピッカーのすべてのサブスクライブを解除することができます。

const productPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
  options: {
    selectMultiple: true,
    showHidden: false,
  },
})

productPicker.subscribe(ResourcePicker.Action.SELECT, () => {
  // `selection`で何かをする
})

productPicker.subscribe(ResourcePicker.Action.CANCEL, () => {
  // ピッカーがキャンセルされました
})

// すべてのアクションから登録解除
productPicker.unsubscribe()

アクションのディスパッチ

const collectionPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Collection,
  options: {
    selectMultiple: true
    showHidden: false,
  }
});

// コレクションピッカーを開く
collectionPicker.dispatch(ResourcePicker.Action.OPEN);

オプションの更新

ピッカーのオプションを部分的に指定して set メソッドを呼び出すことができます。これにより、モーダルの update アクションが自動的に実行され、指定されたオプションが既存のオプションにマージされます。

const collectionPicker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Collection,
  options: {
    selectMultiple: true,
    showHidden: false,
  },
})

collectionPicker.set({ showHidden: true })

Scanner

Scannerアクションセットを使うと、モバイルデバイスのカメラを使ってバーコードをスキャンすることができます。

必要条件

これらのアクションには、以下のアプリのバージョンが必要です。

  • Shopify iOS v8.25.0 またはそれ以上
  • Shopify Android v8.24.0 またはそれ以上
  • Point of Sale iOS v5.32.0以上
  • Point of Sale Android v3.25.0 またはそれ以上

設定方法

アプリを作成し、@shopify/app-bridge/actionsからScannerモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照しています。

import createApp from "@shopify/app-bridge"
import { Group, Scanner } from "@shopify/app-bridge/actions"

var app = createApp({
  apiKey: "12345",
  host: host,
})

var scanner = Scanner.create(app)

スキャナキャプチャアクション

グループ Scanner
アクション CAPTURE
アクションタイプ APP::SCANNER::CAPTURE
説明 スキャンが成功したときにディスパッチします。

スキャナコンポーネントを開くには、まず機能検出を使用して、それが利用可能かどうかを確認する必要があります。利用可能であれば、それを開くことができます。機能検出の詳細については、「機能」を参照してください。

scanner.subscribe(Scanner.Action.CAPTURE, function (payload) {
  // ペイロードには、スキャンされたデータの文字列表現である `scanData` が含まれます。
})

レスポンス

キー タイプ 説明
scanData String? バーコードをスキャンした結果の文字列です。

アクセスと Open Camera アクションを要求

グループ Scanner
アクション OPEN::CAMERA
アクションタイプ APP::SCANNER::OPEN::CAMERA
説明 バーコードをスキャンするためのカメラコンポーネントを開きます。
var features = Features.create(app);
// アップデートアクションをサブスクライブします(許可ダイアログが操作されたときに起動します)。
features.subscribe(Features.Action.REQUEST_UPDATE, function (payload) {
  if (payload.feature[Scanner.Action.OPEN_CAMERA]) {var available = payload.feature[Scanner.Action.OPEN_CAMERA].Dispatch;
    // カメラスキャナのアクションが有効な場合、スキャナを開く
    if (available) {
      scanner.dispatch(Scanner.Action.OPEN_CAMERA)
    }
  }
});
// スキャナーアクションへのアクセスを要求するアクションをディスパッチする
features.dispatch(Features.Action.REQUEST, {)
  feature: Group.Scanner.Action,
  action:  Scanner.Action.OPEN_CAMERA
});

Sharing

Shareアクションでは、「シェアシート」を起動して、iOS や Android 端末上の埋め込みアプリからコンテンツを共有することができます。

必要条件

これらのアクションを実行するには、以下のアプリのバージョンが必要です。

  • Shopify iOS v8.22.0またはそれ以上
  • Shopify Android v8.25.0 またはそれ以上
  • Point of Sale iOS v5.29.0以上
  • Point of Sale Android v3.24.0またはそれ以上

設定方法

アプリを作成し、@shopify/app-bridge/actionsからShareモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照しています。

import createApp from "@shopify/app-bridge"
import { Group, Share } from "@shopify/app-bridge/actions"

var app = createApp({
  apiKey: "12345",
  host: host,
})

var share = Share.create(app)

Share Close アクション

グループ Share
アクション CLOSE
アクションタイプ APP::SHARE::CLOSE
説明 Share シートを閉じた後にディスパッチします。

Shareアクションでは、ペイロードタイプをサポートしているアプリであれば、自分のアプリからユーザーのデバイス上の任意のサードパーティアプリにコンテンツを共有できます。アプリによっては、テキストのみをサポートするものや、URL とテキストをサポートするものがあります。

Share Close のサブスクライブ

share.subscribe(Share.Action.CLOSE, function (payload) {
  // ペイロードには、唯一のプロパティとして `success` が含まれます。これは、シェアが成功した場合には `true` に設定され、アクションがキャンセルされた場合には `false` に設定されます。
})

レスポンス

キー タイプ 説明
success Boolean 共有が成功したか、キャンセルされたかを表します。

シェアオープンアクション

グループ Share
アクション SHOW
アクションタイプ APP::SHARE::SHOW
説明 他のアプリとコンテンツを共有するためのシェアシートを開きます。
share.dispatch(Share.Action.SHOW, {
  text: "Hey check this out!",
  url: "https://www.reallyawesomesite.com",
})

リクエスト

キー タイプ 説明
text String? 共有するテキストです。
url String? 共有する URL

TitleBar

TitleBarアクションセットを使うと、標準化されたタイトルバーにボタンアクションやナビゲーションパンくずを配置することができます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからTitleBarモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { TitleBar } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

タイトルバーの作成

タイトルをMy page titleに設定して、タイトルバーを作成します。

const titleBarOptions = {
  title: "My page title",
}

const myTitleBar = TitleBar.create(app, titleBarOptions)

プライマリボタンを持つタイトルバーの作成

タイトルバーのプライマリボタンをボタンに設定することができます。ボタンについての詳細は、「Button」を参照してください。

const saveButton = Button.create(app, { label: "Save" })
const titleBarOptions = {
  title: "My page title",
  buttons: {
    primary: saveButton,
  },
}

const myTitleBar = TitleBar.create(app, titleBarOptions)

セカンダリーボタンを持つタイトルバーの作成

タイトルバーのセカンダリーボタンを 1 つまたは複数のボタンに設定できます。次の例では、Settingsというラベルを持つセカンダリアクションを作成し、アプリにローカルな設定ページへのリダイレクトをトリガーしています。

詳細は、ButtonRedirectを参照してください。

import { TitleBar, Button, Redirect } from "@shopify/app-bridge/actions"
const settingsButton = Button.create(app, { label: "Settings" })
const redirect = Redirect.create(app)
settingsButton.subscribe("click", () => {
  redirect.dispatch({
    type: Redirect.Action.APP,
    payload: { path: "/settings" },
  })
})
const titleBarOptions = {
  title: "My new title",
  buttons: {
    secondary: [settingsButton],
  },
}
const myTitleBar = TitleBar.create(app, titleBarOptions)

グループ化された副ボタンを持つタイトルバーの作成

タイトルバーの副ボタンは、1 つまたは複数のボタングループに設定できます。次の例では、「More actions」というラベルを持つグループ化されたセカンダリーアクションを作成し、2 つの子ボタンを含んでいます。

詳しくは、ButtonGroupButtonを参照してください。

import { TitleBar, Button, ButtonGroup } from "@shopify/app-bridge/actions"

const button1 = Button.create(app, { label: "Show toast message" })
const button2 = Button.create(app, { label: "Open modal" })

const moreActions = ButtonGroup.create(app, {
  label: "More actions",
  buttons: [button1, button2],
})

const titleBarOptions = {
  title: "My new title",
  buttons: {
    secondary: [moreActions],
  },
}
const myTitleBar = TitleBar.create(app, titleBarOptions)

タイトルバーオプションの更新

既存のタイトルバーのオプションを更新するために、部分的なタイトルバーのオプションで set メソッドを呼び出すことができます。これにより、タイトルバーの update アクションが自動的に開始され、与えられたオプションが既存のオプションに統合されます。

const titleBarOptions = {
  title: "My page title",
}

const myTitleBar = TitleBar.create(app, titleBarOptions)
// タイトルの更新

myTitleBar.set({
  title: "My new title",
})

タイトルバーのプライマリ/セカンダリボタンの更新

タイトルバーに取り付けられたボタンを更新することができます。タイトルバーの子ボタンが更新されると、タイトルバーの update アクションが自動的に実行されます。

import { TitleBar, Button, ButtonGroup } from "@shopify/app-bridge/actions"

const button1 = Button.create(app, { label: "Show toast message" })
const button2 = Button.create(app, { label: "Open modal" })

const moreActions = ButtonGroup.create(app, {
  label: "More actions",
  buttons: [button1, button2],
})

const titleBarOptions = {
  title: "My new title",
  buttons: {
    secondary: [moreActions],
  },
}

const myTitleBar = TitleBar.create(app, titleBarOptions)
// moreボタンのラベルを更新 - 変更は自動的に親タイトルバーに伝搬されます
moreActions.set({
  label: "Additional options",
})

ブレッドクラムでタイトルバーを作成する

ボタンにブレッドクラムオプションを設定することで、タイトルバーでブレッドクラムを有効にすることができます。オプションを未定義に設定すると無効になります。:ブレッドクラムはタイトルがないと表示されません。次の例では、「My Breadcrumb」というラベルのブレッドクラムを作成し、「/breadcrumb-link」にリンクしています。

詳しくは、ButtonRedirectをご覧ください。

import { TitleBar, Button, Redirect } from '@shopify/app-bridge/actions';

const breadcrumb = Button.create(app, { label: 'My Breadcrumb' });

breadcrumb.subscribe(Button.Action.CLICK, () => {)
  app.dispatch(Redirect.toApp({ path: '/breadcrumb-link' }));
});

const titleBarOptions = {
  title: 'My new title',
  breadcrumbs: breadcrumb,
};

const myTitleBar = TitleBar.create(app, titleBarOptions);

タイトルバーの更新をサブスクライブする

subscribeを呼び出すことで、タイトルバーの更新アクションをサブスクライブすることができます。この関数は、アクションのサブスクリプションを解除するために呼び出すことができる関数を返します。

// 上記と同じタイトルバーを使用
const updateUnsubscribe = myTitleBar.subscribe(ButtonGroup.Action.UPDATE, (data) => {
  // ボタングループが更新されたら何かをする
  // データは以下のような形になっています。{id: string, label: string, buttons: [{id: string, label: string, disabled: boolean} ...]}。
})

// 登録解除
updateUnsubscribe()

サブスクライブ解除

unsubscribe を呼び出すと、タイトルバーとその子のサブスクリプションをすべて削除できます。

const settingsButton = Button.create(app, { label: "Settings" })
settingsButton.subscribe("click", () => {
  redirect.dispatch({
    type: Redirect.Action.APP,
    payload: { path: "/settings" },
  })
})
const titleBarOptions = {
  title: "My new title",
  buttons: {
    secondary: [settingsButton],
  },
}
const myTitleBar = TitleBar.create(app, titleBarOptions)

myTitleBar.subscribe(TitleBar.Action.UPDATE, (data) => {
  // udpateアクションで何かをする
})

// ボタングループの更新アクションから退会する
// settingsButton click アクションからのunsubscribe
myTitleBar.unsubscribe()

タイトルバーのアクションからのみアンサブスクライブする

unsubscribefalse を付けて呼び出すと、子のサブスクリプションを残してタイトルバーのサブスクリプションだけを削除できます。例えば、タイトルバーのサブスクリプションは解除したいが、ボタンリスナーは残しておき、ボタンを別のアクション(モーダルなど)で再利用できるようにしたい場合などです。

const settingsButton = Button.create(app, { label: "Settings" })
settingsButton.subscribe("click", () => {
  redirect.dispatch({
    type: Redirect.Action.APP,
    payload: { path: "/settings" },
  })
})
const titleBarOptions = {
  title: "My new title",
  buttons: {
    secondary: [settingsButton],
  },
}
const myTitleBar = TitleBar.create(app, titleBarOptions)

myTitleBar.subscribe(TitleBar.Action.UPDATE, (data) => {
  // udpateアクションで何かをする
  // データは以下のような形になっています。{id: string, title: string, buttons: [{id: string, label: string, disabled: boolean} ...]}
})

// タイトルバーの更新アクションから退会する
myTitleBar.unsubscribe(false)

// settingsButtonをモーダルで再利用する
const modalOptions = {
  title: "My Modal",
  message: "Hello world!",
  footer: { primary: settingsButton },
}

const myModal = Modal.create(app, modalOptions)

Toast

Toastアクションセットは、インターフェイスの下部に表示される邪魔にならないメッセージを表示し、アクションの結果に関する迅速かつ短いフィードバックを提供します。

重要ではないアクションの一般的な確認を伝えるためにToastを使用します。例えば、マーチャントが最近行ったアクションが成功したことを知らせるためにトーストメッセージを表示することができます。

設定方法

アプリを作成し、@shopify/app-bridge/actionsからToastモジュールをインポートします。以下の例では、このサンプルアプリケーションを参照することに注意してください。

import createApp from "@shopify/app-bridge"
import { Toast } from "@shopify/app-bridge/actions"

const app = createApp({
  apiKey: "12345",
  host: host,
})

トースト通知の作成

トースト通知を生成します。

const toastOptions = {
  message: "Product saved",
  duration: 5000,
}
const toastNotice = Toast.create(app, toastOptions)

トーストのエラーメッセージの作成

エラーのトースト通知を生成します。

const toastOptions = {
  message: "Error saving",
  duration: 5000,
  isError: true,
}
const toastError = Toast.create(app, toastOptions)

アクションのサブスクライブ

subscribe を呼び出すと、Toast のアクションをサブスクライブできます。この関数は、アクションのサブスクリプションを解除するために呼び出すことができる関数を返します。

const toastNotice = Toast.create(app, { message: "Product saved" })
const showUnsubscribe = toastNotice.subscribe(Toast.Action.SHOW, (data) => {
  // showアクションで何かをする
})

const clearUnsubscribe = toastNotice.subscribe(Toast.Action.CLEAR, (data) => {
  // clearアクションで何かをする
})

// 登録解除
showUnsubscribe()
clearUnsubscribe()

サブスクライブ解除

unsubscribe を呼び出すと、トーストメッセージの現在のサブスクリプションをすべて解除できます。

const toastNotice = Toast.create(app, { message: "Product saved" })
toastNotice.subscribe(Toast.Action.SHOW, (data) => {
  // showアクションで何かをする
})
toastNotice.subscribe(Toast.Action.CLEAR, (data) => {
  // クリアアクションで何かをする
})

// サブスクライブ解除
toastNotice.unsubscribe()

ショーアクションのディスパッチ

const toastNotice = Toast.create(app, { message: "Product saved" })
toastNotice.dispatch(Toast.Action.SHOW)

アクションのクリアをディスパッチ

const toastNotice = Toast.create(app, { message: "Product saved" })
toastNotice.dispatch(Toast.Action.CLEAR)

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://apps.shopify.com/shopify-application-314?locale=ja&from=daniel

Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。

https://apps.shopify.com/font-picker-1?locale=ja&from=daniel

Discussion

ログインするとコメントできます