🍉

Shopify Checkout UI Extensions でサンキューページにお知らせを表示してみよう

2023/12/10に公開

これは、OPENLOGI Advent Calendar 2023 9日目の投稿記事です。
https://qiita.com/advent-calendar/2023/openlogi

はじめに

物流アウトソーシングのプラットフォームを開発している OPENLOGI の Advent Calendar としてこの記事を書きました。
オープンロジでは、 Shopify などの外部 EC カートサービスとの連携の開発を行っており、日頃から Shopify API を使った開発や、Shopify アプリ連携、Shopify アプリ開発を行っています。

Shopify のチェックアウトが進化してきている

今年の Shopify では、チェックアウトに関するものが多く発表されました。
例えば、Shopify のチェックアウトは長年「配送先住所入力」-> 「送料の決定」-> 「お支払情報の入力」と3画面遷移が走るものだったのが、1度も画面遷移を介さない 1画面チェックアウト (OnePage Checkout) に全ショップで変更されました。

また、Checkout UI Extensions(後続に説明します) に新しい UI コンポーネントが続々と利用可能になり、それを利用したアプリが充実してきています。「Shopify はチェックアウトがカスタマイズできない/しずらい」という印象を過去に持っていた方も、新しいアプリを導入することによってやりたいカスタマイズが実現できるようになっているかもしれません。

チェックアウトの拡張性の高さという観点において、Shopify は他のカートシステムに対する優位性が上がってきたと感じています。

今回は、そんな Shopify チェックアウト拡張エコシステムの中から、比較的最近(2023年11月)導入されたばかりの「サンキューページの Checkout UI Extensions」を紹介し、実際にサンキューページにお知らせバナーを表示させる手順を紹介したいと思います。

Shopify Checkout UI Extensions とは

https://shopify.dev/docs/apps/checkout
Shopify Checkout UI Extensions は、アプリからチェックアウトに独自の機能を持つUIコンポーネントを設置できる仕組み で、2022年に Shopify Plus 限定でリリースされました。
それまでは、チェックアウト画面をカスタマイズする場合、テンプレートファイルを編集する必要があり、拡張性にも制限がありました。Plus マーチャントは、Checkout UI Extensions を使ったアプリをインストールすれば、テーマのカスタマイズ画面で UI ブロック(アプリが提供する UI コンポーネント)を追加するのと同じように、チェックアウトにも簡単に UI コンポーネントを追加できるようになりました。


https://shopify.dev/docs/apps/checkout#how-it-works より

Checkout UI Extensions でカスタマイズできる画面は下記の通りです。

  1. チェックアウト
  2. 購入後一時ページ(post-purchase page)
  3. サンキューページと注文状況ページ // <--- new!

新しく追加された「サンキューページと注文状況ページ」の Checkout UI Extension 化は、Shopify Plus 以外のショップにも適用が予定されています。記事執筆時点では、2024年4月にスターター以外の全プランで適用開始される予定とアナウンスされています。
https://shopify.dev/docs/apps/checkout?shpxid=52b30704-6433-4149-C134-D93DF8C1AFAD#checkout-ui-extensions

Checkout UI Extensions でこんな機能を作れます

開発者は、例えば、Checkout UI Extensions だけ[1]で下記のような機能を作成できます

  • アップセル用コンポーネントの追加
  • 購入後に、特定の商品を買った人のみに適用するディスカウント済の商品を表示
  • 置き配のお届け場所や、宅配ボックスの番号を入力するコンポーネントを追加
  • 「日時指定」のコンポーネントを追加し、商品や配送先の決定後に、日時指定の表示/非表示を切り替える
  • 特定の住所を入力したときのみ、配送状況に関するメッセージを表示する
    などなど。

アプリで追加できる UI コンポーネントは、Shopify が提供しているものしか使うことができませんが、徐々に追加されて、表現の幅が増えてきました(マップやデートピッカーもあります!)。追加可能な UI コンポーネントの一覧はこちら。
https://shopify.dev/docs/api/checkout-ui-extensions/unstable/components

既に公開されている Checkout UI Extensions を使ったアプリはこちら。
https://apps.shopify.com/stories/guide-checkout-ui-extensions?locale=ja

早速作ってみよう!

公式チュートリアルを追って、サンキューページにコンポーネントを追加するアプリを作っていきましょう!
https://shopify.dev/docs/apps/checkout/thank-you-order-status/build?framework=react

準備

  1. Shopify パートナーにまだなっていない場合は、パートナーアカウントを作成しておきます
  2. 開発ストアを Checkout and Customer Accounts Extensibility developer preview モードを選択して作成します(既に作成済の開発ストアではプレビューモードを変えられません)
    • テストしやすいように価格を0円・在庫を追跡しない設定の商品を追加しておきます
    • テストしやすいように無料の送料を追加しておきます
  3. Shopify CLI を使って、Extensions-only アプリを作成します
    まっさらな状態でエディターを開き、下記コマンドを実行します。
    yarn create @shopify/app
    
    アプリ名などを聞かれるので選択します。

    下記のように表示されれば、初期化が完了しました。プロジェクトルートに移動しておきます。

1. アプリに Extension(拡張機能)を作成する

準備で初期化し作成されたプロジェクトディレクトリを見てみると、extensions 配下には .gitkeep しかありません。この extensions ディレクトリで拡張機能を管理していくので、ここに必要なファイルを生成します。

  1. 下記を実行します。
yarn shopify app generate extension
  1. ブラウザからパートナーアカウトに接続するように言われるので、接続します。
  2. 準備で作ったパートナーアカウトに接続されていることを確認し、アプリ名を入力してアプリを新規作成します。
  3. type は Checkout UI を選びます。
  4. 拡張機能に名前を付けて、初期化します。
    アプリにはもう名前をつけました。1アプリに複数の拡張機能を持てるため、識別するための名前をつけます。
  5. 下記のように表示されれば、初期化が完了しました。

これで、extensions 配下に拡張機能に必要なファイルが生成されました。

2. 拡張機能の設定ファイルを編集

extensions/{拡張機能名}/src/Checkout.tsx を開き、reactExtension の第1引数で指定するブロックタイプを purchase.thank-you.block.render に変更して名前付きでエクスポートします。

変更後の Checkout.tsx

import {
  Banner,
  useApi,
  useTranslate,
  reactExtension,
} from '@shopify/ui-extensions-react/checkout';

const thankYouBlock = reactExtension("purchase.thank-you.block.render", () => <Extension />); // 変更箇所
export { thankYouBlock }; // 変更箇所

function Extension() {
  const translate = useTranslate();
  const { extension } = useApi();

  return (
    <Banner title="info-banner">
      {translate('welcome', {target: extension.target})}
    </Banner>
  );
}

使用するターゲットごとに、ターゲットを参照する reactExtension 関数を作成します。
purchase.thank-you プレフィックスのブロックタイプを指定することで、サンキューページに Extension コンポーネントを表示します。

shopify.extension.toml を開き、先ほどエクスポートに指定したブロックタイプを参照するように変更します。

[[extensions.targeting]]
target = "purchase.thank-you.block.render"
module = "./src/Checkout.tsx"
export = "thankYouBlock"

3. 画面で確認

ここまで来たら一度画面で表示を確認してみましょう。
下記、ローカルテスト用コマンドを実行します。

yarn dev

ショップを選ぶように言われるので、準備で作った開発ストアを選択します。
アプリのURLを自動で更新するか聞かれるので yes にします。

プレビュー用のURL(Preview URL)が表示されたら成功です。

Preview URL にアクセスすると、各拡張機能のプレビュー用URLが生成されているので、アクセスしてみます。

サンキューページまで行く必要があるので、商品を購入し、完了します。
サンキューページで拡張機能で作ったバナーが表示されました🎉


yarn dev 時、下記のエラーで終了した場合は、プロジェクトルート直下の node_modulesyarn.lock を削除してから yarn を実行し、その後に再度 yarn dev を実行してみてください。

> shopify app dev

~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/errors/pretty-print.js:4
const wrap = require("wrap-ansi");
             ^

Error [ERR_REQUIRE_ESM]: require() of ES Module ~/sample-thankyou-ext/sample-thankyou/node_modules/wrap-ansi/index.js from ~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/errors/pretty-print.js not supported.
Instead change the require of index.js in ~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/errors/pretty-print.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/errors/pretty-print.js:4:14)
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/handle.js:7:24)
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/errors/index.js:4:16)
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/cli-ux/index.js:4:16)
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/command.js:7:18)
    at Object.<anonymous> (~/sample-thankyou-ext/sample-thankyou/node_modules/@oclif/core/lib/index.js:5:19)
    at async Promise.all (index 0) {
  code: 'ERR_REQUIRE_ESM'
}

3. UI コンポーネントを自由に変更

前述のように、拡張機能で使える UI はたくさんあります。表示するコンポーネントを変えて、色々試してみましょう。jsの変更はリアルタイムで反映されます。
https://shopify.dev/docs/api/checkout-ui-extensions/unstable/components

サンキューページに追加する UI コンポーネントのガイドラインもチェックしましょう。
https://shopify.dev/docs/apps/checkout/thank-you-order-status/ux-guidelines

4. アプリをデプロイ

開発が終わったら、拡張機能を Shopify にコマンドでデプロイします。

yarn deploy

デプロイしました。

パートナーダッシュボードの「アプリ管理」をみると、デプロイしたアプリが反映されており、「拡張機能」に今作った拡張機能が登録されています。

このアプリを開発ストアにインストールします。アプリ一覧から「アプリをテスト」するへ行き、開発ストアを選択します。

インストールすると、チェックアウトエディターからアプリブロックとして追加できるようになります。開発ストアにいき、設定から「チェックアウト」>「カスタマイズ」に行きチェックアウトエディターを開きます。

「ありがとうございます」画面を選択し、「アプリブロックを追加」を押すと、先ほど作った拡張機能が追加できるようになっています。プレビューでもバナーが表示されました🎉


以上でチュートリアルは終わりです。Checkout UI Extension でアプリを作る方法をざっくり理解できたでしょうか?この手順では、アプリの管理画面は作っていませんし、拡張機能に詳細な設定も設けていません。実際にアプリを公開するまでには、アプリ管理画面やカスタマイズ性の高い詳細設定をつくるなどして、進めていきましょう。

最後に

今後、さらに Checkout UI Extensions でカスタマイズ可能な画面が増えていくことが予定されています。
Checkout UI Extensions を使えば、同じチェックアウト画面を複数のアプリがバッティングすることなく機能を提供でき、マーチャントはストレスなくアプリを追加・削除ができるようになります。

チェックアウトのカスタマイズで解決できる既存問題はたくさんあり、我々発送業務に関わる部分でも、業務改善につながるものも多いと感じています。積極的にチェックアウトの拡張機能を利用していければと考えています。


脚注
  1. さらに、Shopify Functions を組み合わせることで、機能を拡張できますが、この記事では、Shopify Functions を扱いません。Shopify Functions については去年の記事もどうぞ。 ↩︎

Discussion