Theme extension 参考
本页是 Theme App Extension 的查阅手册:配置文件、两种区块、Snippets、Schema、资源引用与多语言。开发流程见 创建一个主题扩展。
配置文件(shoplazza.extension.toml)
每个 Theme App Extension 根目录下有一个 shoplazza.extension.toml 配置文件:
id = "617189634367044154"
name = "my-theme-app-extension"
type = "theme"
字段说明:
| 字段 | 说明 |
|---|---|
id | 扩展的唯一 ID,由 CLI 创建扩展时自动生成,不可手动修改。 |
name | 扩展名称,在 CLI 操作和后台管理中使用。 |
type | 固定为 "theme",表示这是一个 Theme App Extension。 |
App Block(应用区块)
App Block 用于在页面中注入内联内容。商家可以在主题编辑器的 Apps 区域将 App Block 手动添加到支持的 Section 中。

适合使用 App Block 的场景:
-
需要指向动态数据源的功能,如商品评分、评论展示。
-
商家可能需要在页面上调整位置的功能。
-
需要横跨页面全宽显示的功能。
注意:App Block 默认不会在安装应用后自动出现在主题中,需要商家在主题编辑器中手动添加。
App Block 对主题的要求
App Block 要正常运行,主题的 Section 必须支持并渲染 @app 类型的 Block。
示例:app_block.liquid
我们将展示一个获取用来获取商品评分元数据的 App Block 的完整示例。
为了能够使代码能够正确允许,我们需要新增average_rating的元数据,并在商品的后台配置该元数据的值:
1、新增元数据字段average_rating

2、在商品后台设置average_rating 的值

3、在商店主题编辑中,在商品详情中,添加该 theme extension

具体代码(blocks/app_block.liquid):
{% use "app_block.css" %}
{%- comment -%} 商品未配置 average_rating 时 default 为 0,避免 nil 导致渲染异常 {%- endcomment -%}
{% assign avg_rating = product.metafields.custom.average_rating | metafield_text | default: 0 | plus: 0 | round %}
<span style="color:{{ block.settings.color }}">
{% render 'rating_stars', rating: avg_rating %}
</span>
{% if avg_rating >= 4 %}
<div class="recommendation-text">
<img src="{{ 'thumbs_up.svg' | asset_abs_url }}" style="width:20px; height:20px;">
{{ 'i18n.ratings.recommendation_text' | t }}
</div>
{% endif %}
{% schema %}
{
"name": {
"en-US": "Product Rating",
"zh-CN": "商品评分"
},
"settings": [
{
"type": "color",
"id": "color",
"label": {
"en-US": "Star Color",
"zh-CN": "星星颜色"
},
"default": "#ff0000"
}
]
}
{% endschema %}
assets/app_block.css
.recommendation-text {
color: green;
}
.myapp-floating-button-wrapper {
color: red;
}
效果展示:

代码说明:
-
{% use "app_block.css" %}:Shoplazza 特有的资源加载方式,用于引入assets/目录中的 CSS 文件(详见后文的 "资源引用" 章节)。 -
block.settings.color:读取 Schema 中定义的color设置项的值,商家可在主题编辑器中修改。 -
{% render 'rating_stars', rating: avg_rating %}:引用snippets/rating_stars.liquid代码片段,并传入参数。 -
{{ 'thumbs_up.svg' | asset_abs_url }}:获取assets/目录中图片的绝对 URL。 -
{{ 'i18n.ratings.recommendation_text' | t }}:多语言翻译,从locales/文件中读取对应语言的文本。 -
Schema 中不设置
target字段时,默认为 App Block(作用于 Section)。
App Embed Block(应用嵌入区块)
App Embed Block 用于没有独立 UI 区域、或需要添加浮动/覆盖层元素的功能。Shoplazza 会在 HTML </head> 或 </body> 闭合标签前渲染并注入 App Embed Block。

在 Schema 中通过 "target" 字段指定注入位置:
| target 值 | 注入位置 |
|---|---|
"body" | </body> 标签前(最常用) |
"head" | </head> 标签前 |
注意:App Embed Block 安装后默认处于停用状态,商家需要在主题编辑器的 主题编辑 > 应用管理 中手动激活。
适合使用 App Embed Block 的场景:
-
浮动按钮、聊天气泡等悬浮组件。
-
SEO meta 标签、数据分析、埋点追踪脚本。
-
在所有页面上生效的全局功能。
示例:app_embed_block.liquid
以下是一个悬浮按钮 App Embed Block 的完整示例(blocks/app_embed_block.liquid)。推荐做法:CSS / JS 写在 assets/ 目录的独立文件中,通过 Liquid 过滤器引入,而不是把 <style> / <script> 内联到 Liquid 文件里——便于复用、CDN 缓存、避免重复加载(详见后文的 "资源引用" 章节)。
{{ 'floating_button.css' | asset_abs_url | stylesheet_tag }}
{{ 'floating_button.js' | asset_abs_url | script_tag }}
<div class="myapp-floating-button-wrapper">
<button
type="button"
class="myapp-floating-button"
style="
background-color: {{ block.settings.background_color }};
color: {{ block.settings.text_color }};
"
>
<span>{{ block.settings.button_label }}</span>
</button>
</div>
{% schema %}
{
"name": {
"en-US": "Floating Button",
"zh-CN": "悬浮按钮"
},
"icon": "https://assets.shoplazza.com/oss/operation/a425c6e10e32f87a1e7271c9ed9347d8.svg",
"target": "body",
"settings": [
{
"type": "text",
"id": "button_label",
"label": {
"en-US": "Button Label",
"zh-CN": "按钮标签"
},
"default": "Help"
},
{
"type": "color",
"id": "background_color",
"label": {
"en-US": "Background Color",
"zh-CN": "背景颜色"
},
"default": "#ff0000"
},
{
"type": "color",
"id": "text_color",
"label": {
"en-US": "Text Color",
"zh-CN": "文字颜色"
},
"default": "#ffffff"
},
{
"type": "text",
"id": "link_url",
"label": {
"en-US": "Click URL",
"zh-CN": "点击跳转链接"
},
"default": "https://www.shoplazza.dev"
}
]
}
{% endschema %}
关于
icon字段:示例中的assets.shoplazza.com是 Shoplazza 内部 CDN 上的占位图标,实际发布时请替换为你自己上传的图标 URL。
assets/floating_button.css
.myapp-floating-button-wrapper {
position: fixed;
bottom: 24px;
right: 24px;
z-index: 9999;
}
.myapp-floating-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 16px;
border-radius: 999px;
font-size: 14px;
font-weight: 600;
text-decoration: none;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
cursor: pointer;
transition:
transform 0.08s ease-out,
box-shadow 0.08s ease-out;
}
.myapp-floating-button:hover {
transform: translateY(-1px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
assets/floating_button.js
document.addEventListener('DOMContentLoaded', () => {
const btn = document.querySelector('.myapp-floating-button');
console.log('悬浮按钮已加载, button element:', btn);
if (!btn) return;
btn.addEventListener('click', event => {
console.log('悬浮按钮已点击');
// 跳转 URL 可通过 schema 的 link_url 设置项传入;这里硬编码仅为示意
window.open('https://www.shoplazza.dev', '_blank');
});
});
效果展示:

代码说明:
-
"target": "body":指定为 App Embed Block,内容注入到</body>前。App Embed Block 必须在 Schema 中显式设置target。 -
"icon":在主题编辑器的应用嵌入列表中显示的图标,使用绝对 URL。 -
block.settings.button_label等:读取商家在主题编辑器中配置的设置值。 -
资源引入: CSS / JS 通过
asset_abs_url | stylesheet_tag与asset_abs_url | script_tag引入外部文件。如果确实需要在 Liquid 中内联<style>/<script>,请把 JS 逻辑包裹在 IIFE 中避免全局变量污染——但推荐还是用外部文件,方便缓存与复用。
Snippets(代码片段)
snippets/ 目录用于存放可复用的 Liquid 代码片段,可在多个 Block 中引用,避免重复代码。
示例:snippets/rating_stars.liquid
{%- if rating < 0 -%}
{%- assign safe_rating = 0 -%}
{%- elsif rating > 5 -%}
{%- assign safe_rating = 5 -%}
{%- else -%}
{%- assign safe_rating = rating -%}
{%- endif -%}
{%- assign blank_stars = 5 | minus: safe_rating -%}
<span aria-label="{{ safe_rating }}/5 stars">
{{ 'i18n.ratings.star_label' | t }}:
{%- for i in (1..safe_rating) -%}
★
{%- endfor -%}
{%- for i in (1..blank_stars) -%}
☆
{%- endfor -%}
</span>
用
if / elsif把rating限制在 0~5 之间(Shoplazza Liquid 不提供at_least/at_most这类 clamp filter,可用的 math filter 见 Math filters),防止评分为负数或大于 5 时渲染异常;外层<span aria-label>为屏幕阅读器提供可读文本。
在 Block 中引用该 Snippet:
{% render 'rating_stars', rating: avg_rating %}
或:
{% include 'rating_stars' %}
{% render %} 与 {% include %} 的区别:
{% render %} | {% include %} | |
|---|---|---|
| 变量作用域 | 独立作用域,不继承外部变量(需通过参数显式传入) | 共享外部变量作用域 |
| 参数传递 | 通过 with、for 或具名参数传递 | 直接访问外部所有变量 |
| 推荐场景 | 需要明确隔离、可复用性强的片段 | 需要访问上下文变量的片段 |
Schema 配置
每个 Block 的 Liquid 文件末尾都需要添加一个 {% schema %} ... {% endschema %} 块,用于定义区块的名称、类型和可配置的设置项。每个文件只能包含一个 {% schema %} 块。
顶级属性
| 属性 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
name | Object | 是 | 在主题编辑器中显示的区块名称。必须同时提供 en-US 和 zh-CN 两种语言。建议不超过 25 个字符。 |
target | String | App Embed Block 必填 | 区块注入位置。App Embed Block 需设置为 "body" 或 "head";App Block 无需设置。 |
icon | String | 否 | 区块在主题编辑器中显示的图标,使用图片绝对 URL。仅 App Embed Block 适用。 |
settings | Array | 否 | 提供给商家的自定义设置项列表,在主题编辑器中选中区块时显示。 |
presets | Array | 否 | 默认配置 |
tag | String | 否 | 如果设置,则用指定 HTML 标签包裹区块输出;不设置时默认用 div 包裹。 |
class | String | 否 | 添加到包裹标签的额外 CSS 类名。 |
name 的多语言格式
name 必须配置为包含 en-US 和 zh-CN 的多语言对象:
{
"name": {
"en-US": "Product Rating",
"zh-CN": "商品评分"
}
}
settings 配置项
每个 setting 对象的结构:
{
"type": "color",
"id": "color",
"label": {
"en-US": "Star Color",
"zh-CN": "星星颜色"
},
"default": "#ff0000"
}
| 字段 | 是否必填 | 说明 |
|---|---|---|
type | 是 | 设置项的控件类型(见下表) |
id | 是 | 设置项的唯一标识,在 Liquid 中通过 block.settings.<id> 访问 |
label | 是 | 在主题编辑器中显示的标签,必须同时提供 en-US 和 zh-CN |
default | 否 | 设置项的默认值 |
常用 type 类型:
| type | 说明 | 示例默认值 |
|---|---|---|
text | 单行文本输入框 | "默认文本" |
textarea | 多行文本输入框 | "多行文本" |
color | 颜色选择器 | "#ff0000" |
select | 下拉选择框(需配合 options 字段) | "option_value" |
checkbox | 勾选框 | true |
range | 滑动范围选择(需配合 min、max、step 字段) | 50 |
image_picker | 图片选择器,让商家从后台上传或选择图片 | — |
在 Liquid 中访问设置值:
{{ block.settings.color }}
{{ block.settings.button_label }}
{{ block.settings.background_color }}
资源引用
方式一:{% use %} 标签(推荐,用于加载 CSS/JS)
{% use %} 是 Shoplazza 提供的 Liquid 标签,用于在 Block 中加载 assets/ 目录下的 CSS 或 JS 文件:
{% use "app_block.css" %}
{% use "app_block.js" %}
特点:
-
如果同一文件在页面上被多个区块引用,只会加载一次,避免重复。
-
CSS 文件会自动在
<head>中注入<link>标签。 -
JS 文件会自动以异步方式加载。
方式二:asset_abs_url 过滤器(用于引用图片等路径)
对于需要在 HTML 属性中动态引用资源路径的场景(如图片 src),使用 asset_abs_url 过滤器获取资源的绝对 URL:
<img src="{{ 'thumbs_up.svg' | asset_abs_url }}">
结合其他过滤器使用:
{{ 'app_embed_block.css' | asset_abs_url | stylesheet_tag }}
{{ 'app_embed_block.js' | asset_abs_url | script_tag }}
注意:在 Theme App Extension 中引用
assets/目录下的资源,必须使用asset_abs_url,而不是主题开发中的asset_url或shoplaza_asset_url。asset_abs_url会根据扩展 ID 和文件哈希生成带唯一标识的路径,确保不同扩展间的同名文件不会冲突。
通过 asset_abs_url 引用的资源文件(图片、CSS、JS 等),文件名不能包含连字符 -,可以使用下划线(_)代替,如 thumbs_up.svg、app_block.css。否则无法生成远程资源。
两种方式的适用场景:
| 使用场景 | 推荐方式 |
|---|---|
| 在 Block 中加载 CSS/JS 文件 | {% use "app_block.css" %} |
| 在 HTML 属性中引用图片或其他资源路径 | {{ 'thumbs_up.svg' | asset_abs_url }} |
动态生成 <link> 或 <script> 标签 | {{ 'app_block.css' | asset_abs_url | stylesheet_tag }} |
多语言(locales)
locales/ 目录存放店面文本的多语言翻译文件,文件命名格式为 {语言代码}.json(如 en-US.json、zh-CN.json、zh-TW.json)。平台支持 15 个地区(含台湾)和 14 个国家的语言文件。
文件格式
locales/en-US.json:
{
"ratings": {
"star_label": "Rating",
"recommendation_text": "Recommended Product!"
}
}
locales/zh-CN.json:
{
"ratings": {
"star_label": "评分",
"recommendation_text": "推荐产品!"
}
}
在 Liquid 中使用翻译
通过 t 过滤器引用翻译键,键名使用点号分隔的路径,并以 i18n. 作为命名空间前缀:
{{ 'i18n.ratings.star_label' | t }}
{{ 'i18n.ratings.recommendation_text' | t }}
平台会根据当前店铺语言自动加载对应语言文件中的翻译文本。
商家无法在主题编辑器中编辑 Theme App Extension 的店面多语言文本,这些文本由开发者在 locales/ 文件中统一维护。