# 构建主题扩展

> 构建 Shoplazza 主题扩展：初始化项目、创建 App Block 与 App Embed Block、在主题编辑器预览并排查问题。

# Theme extension 开发指南

Theme App Extension（主题应用扩展）是主题通用的一种扩展机制，用于将应用能力以扩展形式注入店铺主题。通常由区块文件（blocks）、资源文件（assets）、代码片段（snippets）和多语言文件（locales）组成。

Theme App Extension 支持两种类型的主题扩展：

- 基础扩展（App Block）：用于在页面可视化区域中渲染内容，商家可在主题编辑器中将其添加到支持 `@app` 的 Section。

- 嵌入扩展（App Embed Block）：用于注入全局脚本、浮层或无固定布局区域的能力，通常在 `</head>` 或 `</body>` 前渲染。

![Image](https://cnres.appracle.com/9488c5421dd903207f33e935187c035e.png)

![Image](https://cnres.appracle.com/e103b0ee131955c5af3fa6060874d318.png)

这两种扩展的使用场景、代码结构与 Schema 配置见 [Theme extension 参考](/docs/app/extensions/online-store/reference)。

## 你将学到什么

- 如何用 CLI 初始化并创建一个 Theme App Extension

- App Block 与 App Embed Block 两种扩展类型的区别与适用场景

- 如何编写并预览一个最小可用的 App Block

- 如何编写、启用并预览一个最小的 App Embed Block

## 前置需求

- 已安装 [shoplazza-cli](https://www.npmjs.com/package/shoplazza-cli)，并已登录到测试店铺（`shoplazza app dev` 会把扩展推送到这个店铺）：`shoplazza auth login --store-domain <your-store>.myshoplaza.com --domain app`

- 拥有 Shoplazza 开发者账号与测试店铺

- 已有 shoplazza app 项目，或在空目录中开发

## 开发流程

### 第一步：初始化

在 app 项目根目录（或空目录）执行：

```bash
shoplazza app init --name "my-app"
```

该命令会创建一个名为 `my-app` 的应用，并在当前目录下生成同名项目子目录。

:::tip 已经有应用了？
如果你已按[开发独立应用](/docs/app/getting-started/create-public-app/develop-app)构建了应用，你的工程已具备 CLI 配置——跳过本步，在工程根目录直接从第二步继续。
:::

### 第二步：创建 Theme Extension

进入生成的 app 目录后执行：

```bash
shoplazza app extension create --type theme --name my-theme-app-extension --theme-type basic
```

该命令会在 `extensions/` 目录下创建一个名为 `my-theme-app-extension` 的基础类型主题扩展。如果需要 App Embed Block，将 `basic` 替换为 `embed`。目录结构如下：

```text
my-app/
└── extensions/
  └── my-theme-app-extension/
    ├── assets/
    │   ├── my-theme-app-extension.css
    ├── blocks/
    │   ├── my-theme-app-extension.liquid
    ├── snippets/
    │   └── my-theme-app-extension.liquid
    ├── locales/
    │   ├── en-US.json
    │   └── zh-CN.json
    ├── package.json
    └── shoplazza.extension.toml
```

在 `extensions/my-theme-app-extension/` 目录下进行 Theme Extension 开发。

### 第三步：启动预览

开发过程中，在 app 目录中执行：

```bash
shoplazza app dev
```

扩展会自动发布到绑定店铺，随后可在店铺后台主题编辑器中添加 App Block，或在「主题编辑 > 应用管理」中启用 App Embed Block。

`shoplazza app dev` 只在启动时推送一次扩展，不监听文件变更——每次修改后按 Ctrl+C 停止并重新运行，再刷新主题编辑器。

:::note
扩展只有在所属应用安装到店铺后才会出现在主题编辑器中。如果还没有安装，按[测试应用](/docs/app/getting-started/create-public-app/test-app)操作；尚未实现应用本身的，走其中的场景一安装。
:::

## 目录结构

通过 CLI 创建 Theme App Extension 后，会在项目的 `extensions/` 目录下自动生成包含示例代码的完整目录结构：

```text
└── extensions/
    └── my-theme-app-extension/
        ├── assets/
        │   ├── app_block.css
        │   ├── app_embed_block.css
        │   ├── app_embed_block.js
        │   └── thumbs_up.svg
        ├── blocks/
        │   ├── app_block.liquid          ← App Block
        │   └── app_embed_block.liquid    ← App Embed Block
        ├── snippets/
        │   └── rating_stars.liquid
        ├── locales/
        │   ├── en-US.json
        │   └── zh-CN.json
        ├── package.json
        └── shoplazza.extension.toml
```

**子目录说明：**

|子目录|说明|
|---|---|
|`assets/`|存放 CSS、JavaScript、图片等静态资源，会通过 Shoplazza CDN 分发。在 Liquid 中通过 `{% use %}` 标签或 `asset_abs_url` 过滤器引用。|
|`blocks/`|存放 App Block 和 App Embed Block 的 Liquid 文件，每个文件对应一个独立的区块。|
|`snippets/`|存放可复用的 Liquid 代码片段，可在多个 Block 中通过 `{% render %}` 或 `{% include %}` 引用。|
|`locales/`|存放多语言 JSON 文件，用于店面文本的国际化翻译。|
|`shoplazza.extension.toml`|扩展配置文件，包含扩展的 ID、名称和类型。脚手架自动维护，不需要手动修改。|

各文件的详细配置见 [Theme extension 参考](/docs/app/extensions/online-store/reference)。

## 一个最小 App Block 示例

在 `blocks/` 下新建一个最简单的可渲染区块，商家即可在主题编辑器中添加看到效果：

```liquid
<div class="my-app-block">
  {{ block.settings.text | default: "Hello from app block" }}
</div>

{% schema %}
{
  "name": {
    "en-US": "My App Block",
    "zh-CN": "我的区块"
  },
  "settings": [
    {
      "type": "text",
      "id": "text",
      "label": { "en-US": "Text", "zh-CN": "文本" }
    }
  ]
}
{% endschema %}
```

完整的 Block 类型、Schema、资源引用与多语言，见 [Theme extension 参考](/docs/app/extensions/online-store/reference)。

## 一个最小 App Embed Block 示例

与 App Block（渲染在某个 section 内）不同，App Embed Block 把全局内容注入到 `</head>` 或 `</body>` 之前。它的 Schema **必须**声明 `target`（`"body"` 或 `"head"`）。

编辑 `blocks/app_embed_block.liquid`，写一个最小可渲染的 embed：

```liquid
<div class="my-app-embed">
  {{ block.settings.text | default: "Hello from app embed" }}
</div>

{% schema %}
{
  "name": { "en-US": "My App Embed", "zh-CN": "我的全局嵌入" },
  "target": "body",
  "settings": [
    {
      "type": "text",
      "id": "text",
      "label": { "en-US": "Text", "zh-CN": "文本" }
    }
  ]
}
{% endschema %}
```
:::tip
**App Embed Block 默认是关闭的。** 执行 `shoplazza app dev` 发布扩展后，商家必须在主题编辑器的 **主题编辑 > 应用管理** 中手动开启，否则店面上不会渲染任何内容。
:::
完整的 Schema（含 `target`）、资源引用，以及一个完整的浮动按钮示例，见 [Theme extension 参考](/docs/app/extensions/online-store/reference#app-embed-block)。

## 下一步

- **查配置手册**：见 [Theme extension 参考](/docs/app/extensions/online-store/reference)
- **引导商家安装/启用扩展**：见 [用 Deep Link 引导商家安装/启用扩展](/docs/app/extensions/online-store/deep-link)
- **开发结账扩展**：见 [创建一个结账扩展](/docs/app/extensions/checkout/add-checkout-extension)
- **完整验证应用与扩展**：见[测试应用](/docs/app/getting-started/create-public-app/test-app)

## 排障

### App Embed Block 在店面上没有生效

**问题：** App Embed Block 在店面上没有任何效果。

**原因：** App Embed Block 安装后默认处于关闭状态。

**解决：** 在主题编辑器的 **主题编辑 > 应用管理** 中开启它。

### App Block 在页面上不显示

**问题：** 发布后 App Block 不可见。

**原因：** App Block 不会自动插入，需商家手动添加。

**解决：** 在主题编辑器中，把该区块添加到支持 `@app` 的 Section。
