Shopify 应用怎么接入主题?主题应用扩展、应用块与应用嵌入块详解
过去 Shopify 应用常常直接往主题里写代码,卸载后留下残余、主题升级时容易冲突。现在应用接入 Online Store 2.0 主题的标准方式是主题应用扩展:通过应用块和应用嵌入块,由商家在主题编辑器里放置和开关。本文讲清两种块的区别、主题侧要做的适配,以及响应式和样式隔离的注意事项。
- 上架 App Store 的应用若要修改主题,必须使用主题应用扩展,不能直接改主题代码。
- 应用块是放在 section 里的内联组件,只能用于支持 @app 的 JSON 模板区域。
- 应用嵌入块用于脚本、悬浮按钮等无固定位置的功能,旧版主题也能用,默认关闭。
- 应用块应随所在 section 尺寸自适应,并继承主题的字体和颜色。
- 更换主题后,应用块和应用嵌入块需要在新主题里重新添加和开启。
装过几个 Shopify 应用的商家,大多遇到过这样的情况:评价插件卸载了,商品页上还留着一块空白;换了新主题,之前的尺码表按钮不见了;某个应用更新后,页面布局突然错位。这些问题有一个共同根源:早期很多应用是直接修改主题文件来实现前台展示的,应用和主题的代码搅在一起,谁都说不清某一行是谁加的。
Online Store 2.0 之后,Shopify 给应用提供了一条标准化的接入方式:主题应用扩展(theme app extensions)。本文面向正在开发或采购 Shopify 应用的品牌方和技术人员,说明它是怎么工作的、主题需要做什么配合,以及开发时最容易踩的坑。
一、主题应用扩展是什么
按 Shopify 官方文档,主题应用扩展让商家无需接触 Liquid 模板或代码,就能把应用的动态内容加进主题,例如商品评价、评分、价格展示、3D 模型等。一个扩展由三类资源组成:
- blocks:Liquid 文件,是应用注入主题的入口,分为应用块(app block)和应用嵌入块(app embed block);
- assets:应用要加载的 CSS、JavaScript 和其他静态文件,托管在 Shopify 的 CDN 上;
- snippets:多个 block 之间共用的 Liquid 片段。
此外还有 locales 目录放多语言文案,以及 shopify.extension.toml 配置文件。扩展随应用一起通过 Shopify CLI 部署,开发者发布一次,所有安装了应用的店铺同时生效。
二、为什么不再直接改主题代码
这不只是推荐做法,对上架 App Store 的应用是硬性要求。App Store 要求第 5.1.1 条写明:如果应用会修改商家的主题,就必须使用主题应用扩展,开发者和商家都不应该对主题代码做改动。同一部分还要求应用组件在主题编辑器和前台都能正常显示、没有错误,并为应用块和应用嵌入块提供详细的安装说明。
官方给出的理由可以归纳为几点:
- 商家不用手工改代码,降低了操作门槛和出错概率;
- 应用自动出现在主题编辑器里,可以直接复用编辑器的可视化编辑能力,应用不必自己再做一套页面配置界面;
- 一套接入逻辑适用于所有主题,不用针对每个主题写不同的注入代码;
- 应用不编辑主题代码,也就降低了给主题带来破坏性改动的风险;
- 部署统一,更新一次对所有店铺生效。
对商家来说,最直观的好处是边界清楚:应用的内容在编辑器里以独立的块出现,想挪位置、想关掉,都在编辑器里完成,不需要找开发者翻代码。Shopify 帮助中心在卸载应用的说明里也提醒过,有些应用加进主题的代码不会随卸载自动移除,这正是旧接入方式的遗留问题。
三、应用块和应用嵌入块有什么区别
两种块的定位完全不同。按扩展配置文档,区别主要在以下几方面:
- 应用块:schema 里 target 为 section,是放在页面内容中的内联组件,例如商品页上的评价列表、尺码推荐按钮。商家在编辑器里把它加到兼容的 section 里,可以调整位置和设置;
- 应用嵌入块:target 为 head、body 或 compliance_head,用于没有固定位置的功能,例如统计脚本、悬浮聊天按钮、弹窗,代码被注入到对应 HTML 标签闭合之前。它默认关闭,商家要在主题设置的「应用嵌入」里手动开启;
- 兼容性:应用块只能用在 JSON 模板、并且声明支持 @app 的 section 里,旧版主题用不了;应用嵌入块在旧版主题和 Online Store 2.0 主题里都能用。
两种块都可以用 javascript 和 stylesheet 属性声明要加载的资源,用 enabled_on 或 disabled_on 限制可用的模板或区域,还可以用 available_if 根据应用写入的布尔型元字段决定是否可用,例如只对开通了某项付费功能的店铺显示。
扩展本身也有平台限制,设计时要提前考虑:一个扩展最多 30 个块,全部文件合计不超过 10 MB,所有 Liquid 合计不超过 100 KB。官方还给出了建议上限:压缩后的 CSS 不超过 100 KB,JavaScript 不超过 10 KB。JavaScript 的建议值很低,实践中应让应用块以 Liquid 输出内容为主,脚本只负责必要的交互。
四、主题这一侧要做什么
应用块能不能放进某个位置,取决于主题有没有预留。按主题支持应用块的文档,section 要在 schema 的 blocks 里声明一个 @app 类型,才能接收应用块;这种声明不接受 limit 参数。如果 section 使用 theme block,用 content_for 'blocks' 标签就能渲染;如果使用自带的 section block,就要在遍历 block 时对 @app 类型单独用 render 输出。Dawn 的主商品 section 是官方给出的参考写法。
几个容易忽视的细节:
- 应用块不支持静态渲染的 section,只能出现在 JSON 模板和 section group 里;
- 支持应用块的 section,每种资源类型的设置只能有一个,例如只能有一个商品选择器,否则应用块的自动取值会混乱;
- 商家把应用块直接加到模板顶层时,平台会用主题提供的 apps.liquid 或通用包裹 section 来包一层,主题可以借此统一外边距和容器宽度;
- Theme Store 当前要求主题至少在主商品 section 和精选商品 section 中支持应用块。
如果是定制主题,建议在商品页、购物车、页脚等应用常出现的位置提前声明 @app,将来接入评价、订阅、会员类应用时就不用再改主题。平台扩展方式的整体取舍,可以参考外贸独立站选型对比。
五、响应式与样式隔离:开发时最常踩的坑
应用块运行在别人的主题里,它不知道自己会被放进多宽的容器、周围是什么字体和颜色。Shopify 的主题应用扩展 UX 指南对此有明确要求:应用块要能根据所在 section 的尺寸自适应,并继承主题的字体、颜色等样式。落到开发上,有这样几条经验:
- 不要写死宽度:用百分比、max-width、弹性布局和 clamp() 函数,让块在满宽 section 和窄侧栏里都能正常显示;需要按块自身宽度调整布局时,容器查询比基于视口的媒体查询更可靠;
- 默认继承而不是覆盖:文字颜色、字号、字体尽量用 inherit 或主题暴露的 CSS 变量,不要全局设置 body、h2、button 这类元素的样式;
- 给所有类名加命名空间:用应用专属前缀,把选择器限定在块的根元素之内,避免和主题或其他应用的样式互相污染;需要更强隔离的复杂组件,可以考虑 Shadow DOM,但要评估它对继承主题样式的影响;
- 控制脚本体积和加载方式:按需加载、延迟执行,不要在每个页面都拉一整套前端框架;
- 设置项克制:编辑器里只放必要的、以视觉为主的设置,不要把应用后台的配置搬进主题编辑器;
- 照顾可访问性:头部区域的图标建议不超过 24×24 像素,点击热区保持 44×44 像素,按钮要有可读名称,弹窗要能用键盘关闭。
应用块写得好不好,看的是它放进任何一个主题后,像不像这个主题本来就有的东西。
应用嵌入块同样要注意性能:它往往在每个页面都加载,一个臃肿的嵌入脚本会拖慢整站。上线前建议在装与不装应用两种状态下对比页面性能指标,排查方法可以参考网站性能优化清单。
六、商家和开发者分别该注意什么
对商家和品牌方:
- 选应用时优先确认它是否通过主题应用扩展接入,安装说明里是否写清了应用块和应用嵌入块怎么开;
- 更换主题后,应用块和嵌入块不会自动在新主题里生效,需要在新主题里重新添加和开启;
- 旧主题里如果有早年应用留下的代码,迁移到新主题时是清理的好时机。
对开发者:
- 为应用块写针对不同主题的放置说明,为应用嵌入块提供统一的开启引导,并利用深度链接让商家一键跳转到编辑器预览;
- 在多个官方主题和常见第三方主题里测试显示效果,包括移动端和主题编辑器预览状态;
- 只把展示逻辑放在扩展里,业务数据通过应用后端或元字段提供。
大乐网络为外贸独立站客户做 Shopify 主题和私有应用定制时,也按这套方式接入:主题预留应用位,功能通过扩展交付,避免把业务逻辑直接写进主题文件,后续换主题或停用功能时都更容易收拾。
常见问题
Shopify 应用块和应用嵌入块有什么区别?
应用块是放在页面内容里的组件,例如商品页的评价列表,商家在主题编辑器里把它加到支持 @app 的 section 中,可以调整位置;应用嵌入块用于没有固定位置的功能,例如统计脚本、悬浮聊天按钮,注入到 head 或 body 中,默认关闭,需要在主题设置的应用嵌入里开启。
为什么我的主题里加不了某个应用的应用块?
应用块只能放进 JSON 模板或 section group 里、且 schema 声明了 @app 的 section。旧版主题、静态渲染的 section,或没有声明 @app 的 section 都放不进去。可以换到支持的位置,或请开发者给对应 section 增加 @app 支持。
卸载 Shopify 应用后主题里会留下代码吗?
通过主题应用扩展接入的内容以独立的块存在,由商家在编辑器中管理,不会写进主题文件。但部分早期应用是直接修改主题代码的,Shopify 帮助中心提醒这类代码卸载后不会自动移除,需要查看应用说明或联系开发者清理。
参考资料
- About theme app extensions · Shopify.dev
- Theme app extension configuration · Shopify.dev
- App blocks for themes · Shopify.dev
- UX for theme app extensions · Shopify.dev
- Shopify App Store requirements · Shopify.dev
- CSS container queries · MDN Web Docs
- clamp() · MDN Web Docs