Shopify「新しいお客様アカウント」のマイページに独自機能を組み込む:UI Extensionsでできること・できないこと
この記事の実測情報は、2026年8月にShopify CLI 3.90とapi_version 2026-04の環境で、検証用ストアにextensionを作って確認したものです。公式ドキュメントにある仕様にはリンクを添え、ドキュメントに記載のない挙動は検証ストアで確認したものとして区別して書いています。
はじめに:新しいマイページに「あと一歩」の機能を足したい
新しいお客様アカウントに切り替えたストアでは、会員ランクの表示、過去注文のカスタマイズ内容の表示、注文全体ではなく「この商品だけ再注文」するボタン、外部システムが持つ情報の表示といった要望が出てきます。どれも標準のマイページに少し足せば済みそうに見えますが、新しいマイページはShopifyのホストするUIで、テーマからは触れません。
従来のマイページは、テーマのtemplates/customers/*.liquidを編集すれば作り込めました。新しいお客様アカウントではこのテンプレートが使われず、テーマコードでマイページを作り込む方法そのものがありません。代わりにアプリが独自のUIを差し込む仕組みとして、Customer Account UI Extensions(略してUIE)に一本化されています。
公式ドキュメントを読み、検証用ストアにextensionを作って試すと、UIEでできること、できないことに加え、仕様上は可能でも実機では注意が要ることが分かりました。実装の手順は次の4本で扱います。
- Customer Account UI Extensions開発の始め方:scaffoldから実ストアでの検証まで【実践チュートリアル】
- Customer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分け【実践チュートリアル】
- Shopifyのマイページに「この商品だけ再注文」ボタンを作る:cart permalinkと遷移制約の実装【実践チュートリアル】
- Customer Account UI Extensionsから外部APIを呼ぶ:network_access・CORS・実データでの検証手法【実践チュートリアル】 これからマイページを拡張する人に向けて書いており、移行そのものの手順やスケジュールは、移行ガイドの記事に分けています。従来のお客様アカウント(legacy)は公式に非推奨化されており、新規ストアでは既に選べません。これから作るものは、新しいお客様アカウントを前提に考えることになります。
1. UIEでできること、できないこと、実機で注意が要ること
UIEの可否を「公式仕様として可能」と「公式仕様として不可」の2つに分けるだけでは、設計の材料として足りません。この2つの間に、仕様はあるのに実機では注意が要るという第三のカテゴリがあり、リファレンスだけを読んで設計すると、ここで手戻りが出ます。
表中の「公式」は公式ドキュメントに記載がある項目、「実測」と「確認済み」は公式ドキュメントに記載がなく、2026年8月に検証ストアで確認した挙動です。signalは、extensionの中でshopify.*グローバルとして受け取るデータのことで、2章で説明します。
| 分類 | 項目 | 備考 |
|---|---|---|
| ✅ できる | 過去注文のラインアイテムプロパティ表示 | signalから読めます。_始まりのプロパティも隠されません(実測)。過去注文のデータを読む・書く
|
| ✅ できる | 顧客と注文のメタフィールドの読み書き | 読むにはtomlでの宣言とaccess設定が要り、書くにはmetafieldsSetを使います(公式)。過去注文のデータを読む・書く
|
| ✅ できる | カートへの商品投入 | cart permalinkのURLで商品を渡します(公式)。「この商品だけ再注文」ボタン |
| ✅ できる | 外部APIの直接呼び出し |
network_accessの設定とCORSの条件を満たせば呼べます(公式)。外部APIを呼ぶ
|
| ✅ できる | 新しいページの追加 | フルページextensionとメニュー項目で追加します(公式) |
| ⚠️ 注意 | 空値のラインアイテムプロパティ | signalから欠落します(実測、ドキュメント記載なし)。過去注文のデータを読む・書く |
| ⚠️ 注意 | 注文のcustomAttributes | GraphQLのスキーマにはありませんが、signalでは取れます(確認済み)。過去注文のデータを読む・書く |
| ⚠️ 注意 | 1つのextension内のmodal | 1つまでです。複数置くと後続のブロックが無言で消えます(実測)。過去注文のデータを読む・書く |
| ⚠️ 注意 | バンドルサイズ | 圧縮後64KBが上限で、deploy時に強制されます(公式)。開発の始め方 |
| ⚠️ 注意 | フルページtarget | 他のtargetと同居できず、extensionの分割が要ります(公式)。開発の始め方 |
| ❌ できない | storefront、外部URLへのプログラム遷移 | Navigation APIはアカウント内のみと公式に明文化されています。外への遷移はhrefで行います。「この商品だけ再注文」ボタン |
| ❌ できない | カートAPIの直接操作 | checkout拡張のapplyCartLinesChangeに相当するAPIがありません。「この商品だけ再注文」ボタン
|
| ❌ できない | 販売プラン(サブスク)商品のpermalink投入 | 公式の制約で、実地でも確認済みです。「この商品だけ再注文」ボタン |
| ❌ できない | 任意のHTML/CSS | UIはPolaris Web Componentsに限られます(公式) |
以降では、表に挙げた制約の理由と、制約を踏まえた実装方法を順に説明します。
2. Customer Account UI Extensionsの全体像
構成要素:targets、target APIs、web components
マイページにUIを差し込むときは、差し込む位置、その場所で取れるデータ、画面の描画手段の3つを組み合わせます。公式リファレンスはこの3つを、順にtargets、target APIs、web componentsと呼んでいます。targetsの差し込める場所は事前に定義済みです。差し込み位置ごとに利用できるデータは異なり、target APIsを通じて受け取ります。データの取得経路は、shopify.*グローバルから受け取るsignalとCustomer Account APIの2つに分かれます。web componentsは描画の手段で、<s-text>や<s-button>のようなPolaris Web Componentsを組み合わせて画面を作ります。
実装はPreactベースで、書いたコードはShopifyがホストします。コードが動く場所はsandboxed Web Workerという隔離環境なので、ページのDOMを直接操作できません。テーマコードを編集していた時代とのいちばん大きな違いは、この隔離された実行環境にあります。
差し込み位置(target)の主なカタログ
差し込める位置はtarget一覧にすべて載っています。そこからよく使うものを抜き出したのが次の表で、全量ではありません。
| 場所 | 代表的なtarget | 用途 |
|---|---|---|
| 注文一覧 | customer-account.order-index.block.render |
注文リストに情報を足します |
| 注文詳細 |
customer-account.order-status.block.renderほかrender-after系 |
注文や明細の単位で情報を表示します |
| 注文アクション |
customer-account.order.action.menu-item.render(action.renderとのペア) |
注文メニューにボタンやモーダルを足します |
| プロフィール | customer-account.profile.block.render |
独自項目を表示したり入力させたりします |
| 新規ページ |
customer-account.page.renderとmenu-item |
ウィッシュリストなどの独自ページを作ります |
バンドルサイズの上限:圧縮後64KB
UIEのバンドルには圧縮後64KBの上限があり、公式ドキュメントには「strict 64 KB compressed size limit」と明記されています。この上限はdeploy時に強制されるもので、普段どおりに書いている分には当たらない数字です。ただしライブラリを1つ入れると一気に上限へ近づく水準で、超過したときに何が容量を使っているのかを調べる手順はCustomer Account UI Extensions開発の始め方:scaffoldから実ストアでの検証までで扱います。
フルページ拡張とextensionの分割
フルページのtargetは、2024年10月の公式変更以降、他のtargetと同じextensionに同居できません。ウィッシュリストのような独自ページと既存画面に差し込むブロックを1つのアプリで提供するなら、後から構成を組み替える手戻りを避けるために、extensionの分割を設計の段階で織り込んでおきます。
3. 標準機能が「足りそうで足りない」場面:独自実装のユースケース7選
UIEを使う場面は、マイページをゼロから作るときよりも、標準機能が期待にわずかに届かないときに多くなります。2026年8月に検証ストアで標準の挙動を確かめたうえで選んだ代表例が、次の7つです。実装の重さはまちまちで、7つのうち3つはhrefのリンク1本で済みます。
① 商品単位の再注文
標準のBuy againは、注文に入っていた商品をまとめてカートに戻す機能です。公式の説明も「Add all items from a previous order back to the cart」で、注文の中から1商品だけを選んで買い直す導線はなく、2026年8月に検証ストアの実機でもないことを確かめました。

UIEで補うなら、各明細にcart permalinkを貼ったhrefボタンを置く形になります。各明細にhrefボタンを置く実装手順は、Shopifyのマイページに「この商品だけ再注文」ボタンを作る:cart permalinkと遷移制約の実装に書いています。
② カスタマイズ内容を引き継ぐ再注文
Buy againは、ラインアイテムプロパティを引き継ぎません。検証ストアで確認した挙動で、公式ドキュメントには記載がありません。顧客が選んだオプションや入力値をプロパティに持たせているストアで標準の再注文を使うと、カスタマイズの消えた注文ができてしまいます。
引き継ぐには、signalからプロパティを読み、cart permalinkのpropertiesに載せます。公式仕様に沿った経路で、動作も同じ検証で確かめました。読む側はCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分け、引き継ぐ側はShopifyのマイページに「この商品だけ再注文」ボタンを作る:cart permalinkと遷移制約の実装に分けて書いています。
③ 発送前の進捗表示
標準のマイページが注文に表示する進捗は、確認や発送といった配送とフルフィルメントの段階だけです。予約販売のように発送の前に「製造中」「入荷待ち」といった業務工程が挟まる商品でも、その工程を表す標準機能はありません。どちらも検証ストアで確かめた挙動で、公式ドキュメントに記載はありません。

独自の進捗を出すには、order-statusのblock targetに、メタフィールドか外部APIから取った値を表示します。メタフィールドから出す手順はCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分け、外部APIから取る手順はCustomer Account UI Extensionsから外部APIを呼ぶ:network_access・CORS・実データでの検証手法で扱います。
④ 交換リクエスト
顧客が自分で行える標準のセルフサービスは返品までです。サイズ違いや色違いの交換は、Admin APIを使う独自実装の領域にあたります。軽く始めるなら、注文アクションに「交換を希望する」のmenu-itemを置き、注文情報を付けたフォームへhrefで遷移させる形です。これだけでも、注文を起点にした導線にはなります。
⑤ 領収書と適格請求書
日本のECで要望の多い領収書や適格請求書の発行は、標準のマイページに導線がありません。2026年8月の検証ストアでも見当たりませんでした。発行する手段がアプリや外部システムとして既にあるなら、注文番号をパラメータに載せたmenu-itemのhrefリンクで繋がります。発行処理を新たに作らず、既存の発行手段へ移るhrefリンクだけを追加します。
⑥ プロフィールの独自項目
標準のプロフィール画面にある項目は、氏名、メール、電話、住所といった基本情報に限られます。

ふりがな、生年月日、サイズ情報のような独自項目は、profileのblock targetと顧客メタフィールドの組み合わせで作れます。metafieldsSetで顧客メタフィールドへ書き込む手順は、公式チュートリアルでも確認できます。顧客が入力した値の保存までバックエンドなしで完結し、この点は検証ストアでも確認しました。手順はCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分けにまとめています。
⑦ 注文コンテキスト付き問い合わせ
「この注文について問い合わせたい」という場面で、注文番号を顧客に手で書かせずに済む導線を作れます。注文アクションにmenu-itemを置き、注文番号入りのURLで問い合わせフォームへ飛ばす作りで、⑤と同じくhrefのリンク1本です。
4. バックエンドが要るかどうかの判断
extension側だけで成立した経路
バックエンドを置くかどうかは、機能ごとに「ブラウザで動くextension側だけで成立するか」で決まります。検証ストアで確かめた範囲では、マイページの独自実装で必要になりやすい次の5つは、いずれもextension側だけで完結しました。
| やりたいこと | extension側だけで成立した経路 |
|---|---|
| 過去注文のカスタマイズ内容の表示 | signalのラインアイテムプロパティから読めます |
| 外部システムが持つ情報の表示 | 認証がなくCORSの条件を満たすAPIなら、UIEから直接fetchできます |
| カート投入 | cart permalinkのURLだけで済みます |
| ページ間のデータ引き継ぎ | URLパラメータで渡せます(stateless) |
| 顧客入力の保存 | Customer Account APIのmetafieldsSetで保存できます |
バックエンドが必要になる条件
それでもバックエンドが要る場合はあり、条件は次の3つです。
- 外部APIに認証があり、キーの置き場所が要る場合。ブラウザに配布されるコードに秘匿情報は置けません。
- 注文リソースへの自動書き込みが要る場合。Webhookを起点に転記する処理で、ノーコードの自動化では加工を賄えないときです。
- レガシーデータの書き戻しが要る場合。lazy migrationのwrite側です。
この3つのどれにも当てはまらなければ、サーバーレスの構成が成立します。バックエンドが要るかどうかは、自分たちが何を実装するかより、外部依存の認証方針で決まります。
「APIのURLを隠したい」という理由だけで中継サーバーを挟んでも、認証のないAPIへのアクセス制御は強まりません。ブラウザから呼ぶ認証なしのAPIはURL自体が公開されるためで、保護が要るならAPI側に認証を設けます。
公式も外部通信の前にメタフィールドでの代替を検討するよう案内し、メタフィールドの読み書きを全targetでサポートしています。バックエンドなしで完結する設計は、プラットフォーム側の方針とも合っている形です。
コラム:外部の判定が取れないときのUI
外部APIに依存するUIでは、判定が取れなかったときにどうするかという設計判断を避けて通れません。検証では、外部の判定に依存する操作だけを無効にし、判定を必要としない操作は使える状態にしました。判定なしでも押させるfail-openでは判定のない操作が通り、外部が応答しなければ全部塞ぐfail-closedでは外部に依存しない操作まで使えなくなるためです。無効にした操作には、押せない理由を表示します。この設計の詳細はCustomer Account UI Extensionsから外部APIを呼ぶ:network_access・CORS・実データでの検証手法で説明しています。
5. 目的別の記事一覧
実装の手順とコードは、実践チュートリアル4本に分けています。上から順に読むと一続きのチュートリアルになり、必要な機能が決まっているなら該当する1本だけでも自己完結した作りです。
| 記事 | 内容 | こんな人へ |
|---|---|---|
| 開発の始め方 | scaffoldから実ストア検証まで、環境まわりのつまずきどころをまとめています | まず動かしたい人 |
| 過去注文のデータを読む・書く | signal、GraphQL、メタフィールドの実際の挙動を確かめます | 過去注文や独自データを扱いたい人 |
| 「この商品だけ再注文」ボタン | cart permalink、遷移の制約、完動コードをまとめています | ①と②を実装したい人 |
| 外部APIを呼ぶ | CORSの扱い、検証手法、シリーズ総括です | 外部システムと繋ぎたい人 |
- Customer Account UI Extensions開発の始め方:scaffoldから実ストアでの検証まで【実践チュートリアル】
- Customer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分け【実践チュートリアル】
- Shopifyのマイページに「この商品だけ再注文」ボタンを作る:cart permalinkと遷移制約の実装【実践チュートリアル】
- Customer Account UI Extensionsから外部APIを呼ぶ:network_access・CORS・実データでの検証手法【実践チュートリアル】
FAQ
Q:会員ランクや独自情報をマイページに表示するには?
profileやorder-statusのblock targetにextensionを配置し、メタフィールドから読み出して表示します。読み取りには、tomlでの宣言と、メタフィールド定義側のaccess設定の両方が必要です。手順はCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分けにあります。
Q:顧客が自分で情報を入力したり更新したりできますか?
できます。Customer Account APIのmetafieldsSetで顧客メタフィールドに保存でき、公式チュートリアルもある領域です。バックエンドは要りません。詳しくはCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分けに書いています。
Q:過去の注文のカスタマイズ内容(ラインアイテムプロパティ)も表示できますか?
できます。データを移行しなくても、signalからそのまま読めるためです。ただし、値が空のプロパティはsignalから欠落する挙動を検証で確認しているため、キーが無ければ空値とみなす実装にしておくのが確実です。詳しくはCustomer Account UI Extensionsで過去注文のデータを読む・書く:signal・GraphQL・メタフィールドの使い分けに書いています。
Q:バックエンドサーバーは必須ですか?
必須ではありません。表示、カート投入、データの引き継ぎ、顧客入力の保存までは、UIE単体で完結しました。必要になるのは、外部APIの認証キー、注文への自動書き込み、レガシーデータの書き戻しの3条件のどれかに該当する場合です。判断の材料はこの記事の4章とCustomer Account UI Extensionsから外部APIを呼ぶ:network_access・CORS・実データでの検証手法にあります。
Q:dev previewが実ストアで動かないのですが?
dev previewはdevelopment store専用です。実ストアのデータで検証するなら、deployベースの開発に切り替えます。切り替えの手順はCustomer Account UI Extensions開発の始め方:scaffoldから実ストアでの検証までで説明しています。
参考にした公式ドキュメント
- Customer account UI extensions(リファレンス)
- Targets一覧
- Building apps for customer accounts
- Enable extension capabilities for customer accounts
- About metafields in customer accounts
- Create cart permalinks
- App extensions(64KB上限)
- Legacy customer accounts are now deprecated(changelog)
- Limit for full-page extensions(changelog)
- 新しいお客様アカウントの顧客体験(ヘルプセンター)