shopify-app-bridge

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shopify App Bridge Skill

Shopify App Bridge 技能

Shopify App Bridge is a library that allows you to embed your app directly inside the Shopify Admin. It provides a way to communicate with the host environment to trigger actions and navigation.
[!NOTE] This skill focuses on Shopify App Bridge v3 (NPM package) and App Bridge CDN (v4) patterns. ALWAYS check which version the project is using. The latest standard is often typically App Bridge v4 (CDN-based /
overview
script) but many React apps still use
@shopify/app-bridge-react
(v3/v4 wrapper).
Shopify App Bridge是一款允许你将应用直接嵌入Shopify Admin内部的库,它提供了与宿主环境通信的能力,可触发对应操作和页面导航。
[!注意] 本技能聚焦于**Shopify App Bridge v3(NPM包)App Bridge CDN(v4)**的使用模式,请务必先检查项目正在使用的版本。最新标准通常是App Bridge v4(基于CDN/
overview
脚本),但很多React应用仍然使用
@shopify/app-bridge-react
(v3/v4封装包)。

Core Concepts

核心概念

  • Host: The Shopify Admin (web or mobile).
  • Client: Your embedded app.
  • Actions: Messages sent to the host to trigger UI elements (Toast, Modal) or navigation.
  • 宿主:Shopify Admin(网页端或移动端)。
  • 客户端:你的嵌入式应用。
  • 操作:发送给宿主以触发UI元素(Toast、Modal)或导航的消息。

Setup & Initialization

安装与初始化

Using CDN (App Bridge v4 - Recommended)

使用CDN(App Bridge v4 - 推荐)

In modern Shopify apps, the preferred method is using the CDN script. This automatically exposes the
shopify
global variable, which is the primary entry point for all actions.
html
<script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
<script>
  shopify.config = {
    apiKey: 'YOUR_API_KEY',
    host: new URLSearchParams(location.search).get("host"),
    forceRedirect: true,
  };
</script>
在现代Shopify应用中,优先推荐使用CDN脚本的方式,它会自动暴露
shopify
全局变量,这是所有操作的主要入口。
html
<script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
<script>
  shopify.config = {
    apiKey: 'YOUR_API_KEY',
    host: new URLSearchParams(location.search).get("host"),
    forceRedirect: true,
  };
</script>

debugging & Exploration

调试与功能探索

Once initialized, the
shopify
global variable is available in your browser console.
[!TIP] Explore functionality:
  1. Open Chrome Developer Console in the Shopify Admin.
  2. Switch the frame context to your app's iframe.
  3. Type
    shopify
    to see all available methods and configurations.
初始化完成后,你可以在浏览器控制台中访问
shopify
全局变量。
[!提示] 功能探索步骤
  1. 在Shopify Admin页面打开Chrome开发者控制台。
  2. 将框架上下文切换为你应用的iframe。
  3. 输入
    shopify
    即可查看所有可用方法和配置项。

Using
@shopify/app-bridge-react
(Legacy/Specific Use Cases)

使用
@shopify/app-bridge-react
(旧版/特定使用场景)

If you are strictly using React components or need the Provider context for deeply nested legacy components:
jsx
import { Provider } from '@shopify/app-bridge-react';
// ... configuration setup
如果你只使用React组件,或者需要为深层嵌套的旧组件提供Provider上下文:
jsx
import { Provider } from '@shopify/app-bridge-react';
// ... 配置设置

Common Actions

常用操作

Toast

Toast 提示

Display a temporary success or error message.
javascript
shopify.toast.show('Product saved');
展示临时的成功或错误提示消息。
javascript
shopify.toast.show('Product saved');

Modal

Modal 模态框

Open a modal dialog.
javascript
const modal = await shopify.modal.show({
  title: 'My Modal',
  message: 'Hello world',
  footer: {
    buttons: [
      { label: 'Ok', primary: true, id: 'ok-btn' }
    ]
  }
});

modal.addEventListener('action', (event) => {
    if (event.detail.id === 'ok-btn') {
        modal.hide();
    }
});
打开模态弹窗。
javascript
const modal = await shopify.modal.show({
  title: 'My Modal',
  message: 'Hello world',
  footer: {
    buttons: [
      { label: 'Ok', primary: true, id: 'ok-btn' }
    ]
  }
});

modal.addEventListener('action', (event) => {
    if (event.detail.id === 'ok-btn') {
        modal.hide();
    }
});

Resource Picker

资源选择器

Select products, collections, or variants.
Simple Selection
javascript
const selected = await shopify.resourcePicker({
  type: 'product', // 'product', 'variant', 'collection'
  multiple: true,
});
Pre-selected Resources Useful for editing existing selections.
javascript
const selected = await shopify.resourcePicker({
  type: 'product',
  selectionIds: [
    { id: 'gid://shopify/Product/12345', variants: [{ id: 'gid://shopify/ProductVariant/67890' }] }
  ]
});
Filtered Selection Filter by query or status.
javascript
const selected = await shopify.resourcePicker({
  type: 'product',
  filter: {
    query: 'Sweater', // Initial search query
    variants: false, // Hide variants
    draft: false,   // Hide draft products
  }
});
Handling Selection
javascript
if (selected) {
    console.log(selected);
    // Returns array of selected resources
} else {
    console.log('User cancelled picker');
}
用于选择商品、商品合集或商品变体。
简单选择
javascript
const selected = await shopify.resourcePicker({
  type: 'product', // 'product', 'variant', 'collection'
  multiple: true,
});
预选中资源 适合编辑已有选择的场景。
javascript
const selected = await shopify.resourcePicker({
  type: 'product',
  selectionIds: [
    { id: 'gid://shopify/Product/12345', variants: [{ id: 'gid://shopify/ProductVariant/67890' }] }
  ]
});
筛选选择 可通过搜索关键词或状态筛选资源。
javascript
const selected = await shopify.resourcePicker({
  type: 'product',
  filter: {
    query: 'Sweater', // 初始搜索关键词
    variants: false, // 隐藏商品变体
    draft: false,   // 隐藏草稿商品
  }
});
处理选择结果
javascript
if (selected) {
    console.log(selected);
    // 返回选中的资源数组
} else {
    console.log('User cancelled picker');
}

Navigation / Redirect

导航/重定向

Navigate within the Shopify Admin.
javascript
// Redirect to Admin Section
open('shopify:admin/products', '_top');

// Redirect to internal app route
open('shopify:app/my-route', '_top');
在Shopify Admin内部跳转页面。
javascript
// 跳转到Admin对应板块
open('shopify:admin/products', '_top');

// 跳转到应用内部路由
open('shopify:app/my-route', '_top');

Contextual Save Bar

上下文保存栏

Show a save bar when the user has unsaved changes.
javascript
shopify.saveBar.show();

shopify.saveBar.addEventListener('save', async () => {
    // Perform save...
    shopify.saveBar.hide();
    shopify.toast.show('Saved');
});

shopify.saveBar.addEventListener('discard', () => {
    shopify.saveBar.hide();
});
当用户有未保存的修改时展示保存栏。
javascript
shopify.saveBar.show();

shopify.saveBar.addEventListener('save', async () => {
    // 执行保存逻辑...
    shopify.saveBar.hide();
    shopify.toast.show('Saved');
});

shopify.saveBar.addEventListener('discard', () => {
    shopify.saveBar.hide();
});

Best Practices

最佳实践

[!IMPORTANT] Authentication: Ensure your app handles the OAuth flow and generates a session token. Requests to your backend MUST include the session token (Bearer token) if you rely on Shopify authentication. App Bridge handles fetching this token automatically in many configurations.
[!TIP] Navigation: When building a Remix app, use the
@shopify/shopify-app-remix
helpers to handle headers and bridging automatically where possible.
[!WARNING] Host Parameter: The
host
parameter is CRITICAL for App Bridge to work. It must be present in the URL or passed to the config. It is a base64 encoded string provided by Shopify.
[!重要] 身份认证:确保你的应用处理了OAuth流程并生成会话令牌。如果你依赖Shopify认证,向后端发送的请求必须包含会话令牌(Bearer令牌),大多数配置下App Bridge会自动处理该令牌的获取。
[!提示] 导航:如果你在构建Remix应用,尽可能使用
@shopify/shopify-app-remix
辅助工具自动处理请求头和桥接逻辑。
[!警告] Host参数
host
参数对App Bridge的运行至关重要,它必须存在于URL中或者被传入配置中,该参数是Shopify提供的base64编码字符串。

References

参考文档

  • Modal Max - Full-screen modal dialogs for complex multi-step flows, editors, and wizards
  • Save Bar - Contextual save bar for indicating unsaved form changes
  • Modal Max - 适用于复杂多步流程、编辑器和向导的全屏模态框
  • Save Bar - 用于提示表单未保存修改的上下文保存栏