wix-cli-embedded-script

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Wix Embedded Script Builder

Wix 嵌入式脚本构建工具

Creates embedded script extensions for Wix CLI applications. Embedded scripts are HTML code fragments that get injected into the DOM of Wix sites, enabling integration with third-party services, analytics tracking, advertising, and custom JavaScript functionality.
为Wix CLI应用创建嵌入式脚本扩展。嵌入式脚本是会被注入到Wix网站DOM中的HTML代码片段,可实现与第三方服务、分析跟踪、广告以及自定义JavaScript功能的集成。

Quick Start Checklist

快速开始清单

Follow these steps in order when creating an embedded script:
  1. Create script folder:
    src/site/embedded-scripts/<script-name>/
  2. Create
    embedded.html
    with config element, styles, and script logic
  3. Create
    extensions.ts
    with
    extensions.embeddedScript()
    and unique UUID
  4. Create dashboard config page:
    src/dashboard/pages/<script-name>-settings/
  5. Implement config page with
    embeddedScripts
    API from
    @wix/app-management
  6. Update
    src/extensions.ts
    to import and use both extensions
  7. Run
    npx tsc --noEmit
    to verify TypeScript compiles
  8. Run
    npx wix build
    and
    npx wix preview
    to test
  9. Add the
    APPS.MANAGE_EMBEDDED_SCRIPT
    permission in the Wix Dev Center (see Enable Embedded Script Permission)
创建嵌入式脚本时,请按以下步骤依次操作:
  1. 创建脚本文件夹:
    src/site/embedded-scripts/<script-name>/
  2. 创建
    embedded.html
    文件,包含配置元素、样式和脚本逻辑
  3. 创建
    extensions.ts
    文件,使用
    extensions.embeddedScript()
    并配置唯一UUID
  4. 创建仪表板配置页面:
    src/dashboard/pages/<script-name>-settings/
  5. 使用
    @wix/app-management
    中的
    embeddedScripts
    API实现配置页面
  6. 更新
    src/extensions.ts
    以导入并使用上述两个扩展
  7. 运行
    npx tsc --noEmit
    验证TypeScript编译通过
  8. 运行
    npx wix build
    npx wix preview
    进行测试
  9. 在Wix开发者中心添加
    APPS.MANAGE_EMBEDDED_SCRIPT
    权限(参见启用嵌入式脚本权限

Script Types

脚本类型

Embedded scripts must declare a type for consent management:
TypeDescriptionUse Cases
ESSENTIAL
Core functionality crucial to site operationAuthentication, security features
FUNCTIONAL
Remembers user choices to improve experienceLanguage preferences, UI customization
ANALYTICS
Provides statistics on how visitors use the siteGoogle Analytics, Hotjar, Mixpanel
ADVERTISING
Provides visitor data for marketing purposesFacebook Pixel, Google Ads, retargeting
Selection rule: If a script falls into multiple types, choose the option closest to the bottom of the list (most restrictive). For example, a script with both Analytics and Advertising aspects should be typed as
ADVERTISING
.
嵌入式脚本必须声明类型以用于同意管理:
类型描述使用场景
ESSENTIAL
对网站运行至关重要的核心功能身份验证、安全功能
FUNCTIONAL
记住用户选择以提升体验的功能语言偏好、UI自定义
ANALYTICS
提供访客网站使用情况统计的功能Google Analytics、Hotjar、Mixpanel
ADVERTISING
为营销目的提供访客数据的功能Facebook Pixel、Google Ads、重定向广告
选择规则: 如果一个脚本属于多种类型,请选择列表最下方的选项(限制最严格的)。例如,同时具备分析和广告属性的脚本应归类为
ADVERTISING

Placement Options

嵌入位置选项

PlacementDescriptionBest For
HEAD
Between
<head>
and
</head>
tags
Analytics, early initialization
BODY_START
Immediately after opening
<body>
tag
Critical functionality, noscript
BODY_END
Immediately before closing
</body>
tag
Non-blocking scripts, performance
Selection guidelines:
  • Analytics/tracking →
    HEAD
    (initialize early)
  • Advertising pixels →
    BODY_END
    (non-blocking)
  • Critical functionality →
    HEAD
    or
    BODY_START
  • Non-critical features →
    BODY_END
    (better performance)
位置描述最佳适用场景
HEAD
位于
<head>
</head>
标签之间
分析跟踪、早期初始化
BODY_START
紧跟在
<body>
起始标签之后
关键功能、noscript代码
BODY_END
紧跟在
</body>
结束标签之前
非阻塞脚本、性能优化场景
选择指南:
  • 分析/跟踪脚本 →
    HEAD
    (尽早初始化)
  • 广告像素 →
    BODY_END
    (非阻塞)
  • 关键功能 →
    HEAD
    BODY_START
  • 非关键功能 →
    BODY_END
    (性能更优)

Dynamic Parameters and Dashboard Configuration

动态参数与仪表板配置

Every embedded script requires a companion dashboard page to configure its parameters. Site owners use the dashboard page UI to set values, which are then passed to the embedded script as template variables.
每个嵌入式脚本都需要一个配套的仪表板页面来配置其参数。网站所有者通过仪表板页面UI设置值,这些值随后会作为模板变量传递给嵌入式脚本。

Architecture Flow

架构流程

Dashboard Page (React UI)
    │  embeddedScripts.embedScript({ parameters: {...} })
Wix App Management API
    │  Stores parameters, injects as template variables
Embedded Script (HTML)
    │  {{parameterKey}} → actual value
Site DOM
Related skill: Use
wix-cli-dashboard-page
to create the configuration UI for your embedded script.
仪表板页面(React UI)
    │  embeddedScripts.embedScript({ parameters: {...} })
Wix 应用管理API
    │  存储参数,作为模板变量注入
嵌入式脚本(HTML)
    │  {{parameterKey}} → 实际值
网站DOM
相关技能: 使用
wix-cli-dashboard-page
为你的嵌入式脚本创建配置UI。

Parameter Types

参数类型

TypeDescriptionDashboard Component
TEXT
Single-line textInput
NUMBER
Numeric valueInput type="number"
BOOLEAN
True/false toggleToggleSwitch, Checkbox
IMAGE
Image from media managerImagePicker
DATE
Date onlyDatePicker
DATETIME
Date with timeDatePicker + TimeInput
URL
URL with validationInput
SELECT
Dropdown optionsDropdown
COLOR
Color valueColorPicker
类型描述仪表板组件
TEXT
单行文本输入框
NUMBER
数值数字输入框(type="number")
BOOLEAN
真假切换切换开关、复选框
IMAGE
媒体管理器中的图片图片选择器
DATE
仅日期日期选择器
DATETIME
日期加时间日期选择器 + 时间输入框
URL
带验证的URL输入框
SELECT
下拉选项下拉菜单
COLOR
颜色值颜色选择器

Template Variable Syntax

模板变量语法

Embedded scripts support parameterization using template variable syntax
{{variableName}}
. These parameters are configured through the dashboard and passed as template variables that should be used in your HTML/JavaScript code.
Usage Instructions:
  1. Template Variable Syntax:
    • Use
      {{parameterKey}}
      syntax to insert parameter values into your HTML
    • Template variables work in HTML attributes
    • They will be replaced with actual values when the script is injected
  2. HTML Attributes (REQUIRED):
    • Store ALL parameter values in data attributes on a configuration element
    • Template variables can ONLY be used here, not directly in JavaScript
    • Example:
      <div id="config" data-headline="{{headline}}" data-text="{{text}}"></div>
  3. JavaScript Access:
    • JavaScript must read parameter values from the data attributes
    • Use
      getAttribute()
      or the
      dataset
      property
    • Examples:
      javascript
      const config = document.getElementById("config");
      const headline = config?.getAttribute("data-headline");
      // OR using dataset:
      const { headline, text } = config.dataset;
  4. Type Safety:
    • Be aware of parameter types when using them in JavaScript
    • NUMBER types: convert with
      Number()
      or
      parseInt()
    • BOOLEAN types: compare with
      'true'
      or
      'false'
      strings
    • DATE/DATETIME: parse with
      new Date()
  5. Required vs Optional:
    • Required parameters will always have values
    • Optional parameters may be empty - handle gracefully
    • Provide fallback values for optional parameters
  6. Relevant Parameter Usage:
    • Only use dynamic parameters that are relevant to your current use case
    • Ignore parameters that don't apply to the functionality you're implementing
    • Each parameter you use should serve a clear purpose in the script's functionality
    • It's perfectly fine to not use all parameters if they're not applicable
Example Patterns:
Pattern 1 - Configuration in Data Attributes:
html
<div
  id="script-config"
  data-api-key="{{apiKey}}"
  data-enabled="{{enabled}}"
  data-color="{{primaryColor}}"
></div>
<script>
  const config = document.getElementById("script-config");
  const apiKey = config.getAttribute("data-api-key");
  const enabled = config.getAttribute("data-enabled") === "true";
  const color = config.getAttribute("data-color");

  if (enabled && apiKey) {
    // Initialize with configuration
  }
</script>
Pattern 2 - Using dataset Property:
html
<div
  id="script-config"
  data-headline="{{headline}}"
  data-message="{{message}}"
  data-image-url="{{imageUrl}}"
></div>
<script>
  const config = document.getElementById("script-config");
  const { headline, message, imageUrl } = config.dataset;

  // Use the variables in your script logic
  if (headline) {
    document.querySelector("#headline").textContent = headline;
  }
</script>
Pattern 3 - Conditional Logic:
html
<div
  id="config"
  data-mode="{{activationMode}}"
  data-start="{{startDate}}"
  data-end="{{endDate}}"
></div>
<script>
  const config = document.getElementById("config");
  const mode = config.getAttribute("data-mode");

  if (mode === "timed") {
    const startDate = new Date(config.getAttribute("data-start"));
    const endDate = new Date(config.getAttribute("data-end"));
    const now = new Date();

    if (now >= startDate && now <= endDate) {
      // Show content
    }
  } else if (mode === "active") {
    // Show content immediately
  }
</script>
Validation Requirements:
  • Only use dynamic parameters that are relevant to your specific use case
  • Ignore parameters that don't apply to the functionality being implemented
  • Template variables
    {{parameterKey}}
    must match the exact key names from the parameter definitions
  • Handle both required and optional parameters appropriately
  • Provide sensible default behavior when optional parameters are not set
  • Ensure type-appropriate usage (don't use NUMBER parameters as strings without conversion)
嵌入式脚本支持使用
{{variableName}}
的模板变量语法进行参数化。这些参数通过仪表板配置,并作为模板变量传入,应在你的HTML/JavaScript代码中使用。
使用说明:
  1. 模板变量语法:
    • 使用
      {{parameterKey}}
      语法将参数值插入到HTML中
    • 模板变量可用于HTML属性
    • 脚本注入时,它们会被替换为实际值
  2. HTML属性(必填):
    • 将所有参数值存储在配置元素的data属性中
    • 模板变量只能在此处使用,不能直接在JavaScript中使用
    • 示例:
      <div id="config" data-headline="{{headline}}" data-text="{{text}}"></div>
  3. JavaScript访问:
    • JavaScript必须从data属性中读取参数值
    • 使用
      getAttribute()
      dataset
      属性
    • 示例:
      javascript
      const config = document.getElementById("config");
      const headline = config?.getAttribute("data-headline");
      // 或使用dataset:
      const { headline, text } = config.dataset;
  4. 类型安全:
    • 在JavaScript中使用时要注意参数类型
    • 数值类型:使用
      Number()
      parseInt()
      转换
    • 布尔类型:与
      'true'
      'false'
      字符串比较
    • 日期/日期时间:使用
      new Date()
      解析
  5. 必填与可选参数:
    • 必填参数始终有值
    • 可选参数可能为空 - 需优雅处理
    • 为可选参数提供回退值
  6. 相关参数使用:
    • 仅使用与当前用例相关的动态参数
    • 忽略与实现功能无关的参数
    • 每个使用的参数都应在脚本功能中发挥明确作用
    • 如果某些参数不适用,完全可以不使用
示例模式:
模式1 - 配置存储在Data属性中:
html
<div
  id="script-config"
  data-api-key="{{apiKey}}"
  data-enabled="{{enabled}}"
  data-color="{{primaryColor}}"
></div>
<script>
  const config = document.getElementById("script-config");
  const apiKey = config.getAttribute("data-api-key");
  const enabled = config.getAttribute("data-enabled") === "true";
  const color = config.getAttribute("data-color");

  if (enabled && apiKey) {
    // 使用配置初始化
  }
</script>
模式2 - 使用dataset属性:
html
<div
  id="script-config"
  data-headline="{{headline}}"
  data-message="{{message}}"
  data-image-url="{{imageUrl}}"
></div>
<script>
  const config = document.getElementById("script-config");
  const { headline, message, imageUrl } = config.dataset;

  // 在脚本逻辑中使用变量
  if (headline) {
    document.querySelector("#headline").textContent = headline;
  }
</script>
模式3 - 条件逻辑:
html
<div
  id="config"
  data-mode="{{activationMode}}"
  data-start="{{startDate}}"
  data-end="{{endDate}}"
></div>
<script>
  const config = document.getElementById("config");
  const mode = config.getAttribute("data-mode");

  if (mode === "timed") {
    const startDate = new Date(config.getAttribute("data-start"));
    const endDate = new Date(config.getAttribute("data-end"));
    const now = new Date();

    if (now >= startDate && now <= endDate) {
      // 显示内容
    }
  } else if (mode === "active") {
    // 立即显示内容
  }
</script>
验证要求:
  • 仅使用与特定用例相关的动态参数
  • 忽略与实现功能无关的参数
  • 模板变量
    {{parameterKey}}
    必须与参数定义中的键名完全匹配
  • 正确处理必填和可选参数
  • 当可选参数未设置时,提供合理的默认行为
  • 确保类型匹配的使用(不要不转换就将数值参数作为字符串使用)

Common Parameters

常用参数

Every embedded script should have at minimum an enable/disable toggle parameter:
ParameterTypePurpose
enabled
BOOLEAN
Allow site owner to activate/disable
apiKey
TEXT
Third-party service credentials
trackingId
TEXT
Analytics/pixel identifiers
headline
TEXT
Customizable display text
color
COLOR
UI customization
每个嵌入式脚本至少应包含一个启用/禁用切换参数:
参数类型用途
enabled
BOOLEAN
允许网站所有者激活/禁用脚本
apiKey
TEXT
第三方服务凭证
trackingId
TEXT
分析/像素标识符
headline
TEXT
可自定义的显示文本
color
COLOR
UI自定义

Output Structure

输出结构

A complete embedded script implementation requires two parts:
完整的嵌入式脚本实现需要两部分

1. Embedded Script Extension

1. 嵌入式脚本扩展

src/site/embedded-scripts/
└── {script-name}/
    ├── embedded.html     # HTML/JavaScript code to inject
    └── extensions.ts     # Metadata (scriptType, placement)
src/site/embedded-scripts/
└── {script-name}/
    ├── embedded.html     # 要注入的HTML/JavaScript代码
    └── extensions.ts     # 元数据(scriptType、placement)

2. Dashboard Configuration Page (Required)

2. 仪表板配置页面(必填)

src/dashboard/
├── withProviders.tsx     # WDS provider wrapper (required)
└── pages/
    └── {script-name}-settings/
        ├── extensions.ts  # Extension registration (REQUIRED)
        └── page.tsx       # Configuration UI using embeddedScripts API
Note: The dashboard page requires its own
extensions.ts
file. Without this file, the dashboard page will not appear in the Wix dashboard.
WARNING: The dashboard page uses DIFFERENT field names than embedded scripts:
  • Dashboard pages use
    title
    ,
    routePath
    ,
    component
  • Embedded scripts use
    name
    ,
    source
    ,
    placement
    ,
    scriptType
Do NOT apply embedded script field names to dashboard page registrations.
See
wix-cli-dashboard-page
skill
for dashboard page implementation details and the extension registration pattern.
src/dashboard/
├── withProviders.tsx     # WDS提供者包装器(必填)
└── pages/
    └── {script-name}-settings/
        ├── extensions.ts  # 扩展注册(必填)
        └── page.tsx       # 使用embeddedScripts API的配置UI
注意: 仪表板页面需要自己的
extensions.ts
文件。没有此文件,仪表板页面将不会出现在Wix仪表板中。
警告: 仪表板页面使用的字段名称与嵌入式脚本不同:
  • 仪表板页面使用
    title
    routePath
    component
  • 嵌入式脚本使用
    name
    source
    placement
    scriptType
不要将嵌入式脚本的字段名称应用于仪表板页面注册。
请参阅
wix-cli-dashboard-page
技能
了解仪表板页面实现细节和扩展注册模式。

Implementation Pattern

实现模式

html
<!-- Configuration element with template variables -->
<div id="my-config" data-api-key="{{apiKey}}" data-enabled="{{enabled}}"></div>

<!-- Container for dynamic content -->
<div id="my-container"></div>

<style>
  /* Scoped styles for the embedded content */
  #my-container {
    /* styles */
  }
</style>

<script type="module">
  // Get configuration from data attributes
  const config = document.getElementById("my-config");
  if (!config) throw new Error("Config element not found");

  const { apiKey, enabled } = config.dataset;

  // Exit early if disabled (use throw at module scope, not return)
  if (enabled !== "true") {
    throw new Error("Script disabled");
  }

  // Implement functionality in a named function (return is allowed here)
  async function initialize() {
    try {
      // Your implementation
    } catch (error) {
      console.error("Script error:", error);
    }
  }

  // Initialize when DOM is ready
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initialize);
  } else {
    initialize();
  }
</script>
html
<!-- 包含模板变量的配置元素 -->
<div id="my-config" data-api-key="{{apiKey}}" data-enabled="{{enabled}}"></div>

<!-- 动态内容容器 -->
<div id="my-container"></div>

<style>
  /* 嵌入式内容的作用域样式 */
  #my-container {
    /* 样式 */
  }
</style>

<script type="module">
  // 从data属性获取配置
  const config = document.getElementById("my-config");
  if (!config) throw new Error("未找到配置元素");

  const { apiKey, enabled } = config.dataset;

  // 如果禁用则提前退出(在模块作用域使用throw,不要用return)
  if (enabled !== "true") {
    throw new Error("脚本已禁用");
  }

  // 在命名函数中实现功能(此处允许使用return)
  async function initialize() {
    try {
      // 你的实现代码
    } catch (error) {
      console.error("脚本错误:", error);
    }
  }

  // DOM准备就绪时初始化
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initialize);
  } else {
    initialize();
  }
</script>

Examples

示例

Analytics Tracking

分析跟踪

Request: "Add Google Analytics tracking to my site"
Output:
  • Script type:
    ANALYTICS
  • Placement:
    HEAD
  • Template variables:
    {{trackingId}}
  • Implements: gtag.js initialization, page view tracking
需求: "为我的网站添加Google Analytics跟踪"
输出:
  • 脚本类型:
    ANALYTICS
  • 嵌入位置:
    HEAD
  • 模板变量:
    {{trackingId}}
  • 实现内容: gtag.js初始化、页面浏览跟踪

Popup/Modal

弹窗/模态框

Request: "Create a coupon popup that shows when cart value exceeds $50"
Output:
  • Script type:
    FUNCTIONAL
  • Placement:
    BODY_END
  • Template variables:
    {{couponCode}}
    ,
    {{minimumCartValue}}
    ,
    {{enablePopup}}
  • Implements: Cart value detection, popup display logic, localStorage for "don't show again"
需求: "创建一个当购物车金额超过50美元时显示的优惠券弹窗"
输出:
  • 脚本类型:
    FUNCTIONAL
  • 嵌入位置:
    BODY_END
  • 模板变量:
    {{couponCode}}
    ,
    {{minimumCartValue}}
    ,
    {{enablePopup}}
  • 实现内容: 购物车金额检测、弹窗显示逻辑、localStorage用于"不再显示"

Third-Party Chat Widget

第三方聊天组件

Request: "Integrate Intercom chat widget"
Output:
  • Script type:
    FUNCTIONAL
  • Placement:
    BODY_END
  • Template variables:
    {{appId}}
    ,
    {{userEmail}}
    ,
    {{userName}}
  • Implements: Intercom SDK initialization, user identification
需求: "集成Intercom聊天组件"
输出:
  • 脚本类型:
    FUNCTIONAL
  • 嵌入位置:
    BODY_END
  • 模板变量:
    {{appId}}
    ,
    {{userEmail}}
    ,
    {{userName}}
  • 实现内容: Intercom SDK初始化、用户识别

Best Practices

最佳实践

  • Always create a dashboard page: Every embedded script needs a configuration UI
  • Include enable/disable toggle: Let site owners control activation without removing the script
  • Performance: Minimize impact - scripts should be lightweight and non-blocking
  • Security: Avoid inline event handlers, validate data, escape user input
  • Error handling: Fail silently when appropriate - don't break the site
  • Module scope early exits: Use
    throw new Error()
    for early exits at module scope, not
    return
    . Rollup (used by Astro) doesn't allow
    return
    statements at module scope. Wrap main logic in a named async function where
    return
    is valid.
  • Type conversions: Parameters are always strings - convert in JavaScript as needed
  • API calls: Only create fetch() calls to /api/* endpoints that exist in the API spec
  • Scoping: Prefix CSS classes and IDs to avoid conflicts with site styles
  • Cleanup: Remove event listeners and intervals when appropriate
  • 始终创建仪表板页面: 每个嵌入式脚本都需要配置UI
  • 包含启用/禁用切换: 让网站所有者无需移除脚本即可控制激活状态
  • 性能优化: 最小化影响 - 脚本应轻量且非阻塞
  • 安全: 避免内联事件处理器、验证数据、转义用户输入
  • 错误处理: 适当时静默失败 - 不要破坏网站
  • 模块作用域提前退出: 在模块作用域使用
    throw new Error()
    提前退出,不要用
    return
    。Rollup(Astro使用)不允许在模块作用域使用
    return
    。将主逻辑包装在命名异步函数中,此处允许使用
    return
  • 类型转换: 参数始终是字符串 - 在JavaScript中按需转换
  • API调用: 仅调用API规范中存在的/api/*端点
  • 作用域: 为CSS类和ID添加前缀以避免与网站样式冲突
  • 清理: 适当时移除事件监听器和定时器

Complete Example: Coupon Popup

完整示例:优惠券弹窗

1. Define Parameters

1. 定义参数

Parameters for "cart-coupon-popup":
- couponCode (TEXT, required) - The coupon code to display
- popupHeadline (TEXT, required) - Headline text
- popupDescription (TEXT, required) - Description text
- minimumCartValue (NUMBER) - Minimum cart value to show popup
- enablePopup (BOOLEAN, required) - Enable/disable toggle
"cart-coupon-popup"的参数:
- couponCode(TEXT,必填)- 要显示的优惠券代码
- popupHeadline(TEXT,必填)- 弹窗标题文本
- popupDescription(TEXT,必填)- 弹窗描述文本
- minimumCartValue(NUMBER)- 显示弹窗的最低购物车金额
- enablePopup(BOOLEAN,必填)- 启用/禁用切换

2. Embedded Script (
embedded.html
)

2. 嵌入式脚本(
embedded.html

html
<div
  id="popup-config"
  data-coupon-code="{{couponCode}}"
  data-popup-headline="{{popupHeadline}}"
  data-minimum-cart-value="{{minimumCartValue}}"
  data-enable-popup="{{enablePopup}}"
></div>
<div id="popup-container"></div>

<script type="module">
  // Get configuration from data attributes
  const config = document.getElementById("popup-config");
  if (!config) throw new Error("Config element not found");

  const { couponCode, popupHeadline, minimumCartValue, enablePopup } =
    config.dataset;

  // Exit early if disabled (use throw at module scope, not return)
  if (enablePopup !== "true") {
    throw new Error("Popup disabled");
  }

  // Main logic in a function (return is allowed here)
  async function initializePopup() {
    const minValue = Number(minimumCartValue) || 0;
    // ... popup implementation
  }

  // Initialize when DOM is ready
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initializePopup);
  } else {
    initializePopup();
  }
</script>
html
<div
  id="popup-config"
  data-coupon-code="{{couponCode}}"
  data-popup-headline="{{popupHeadline}}"
  data-minimum-cart-value="{{minimumCartValue}}"
  data-enable-popup="{{enablePopup}}"
></div>
<div id="popup-container"></div>

<script type="module">
  // 从data属性获取配置
  const config = document.getElementById("popup-config");
  if (!config) throw new Error("未找到配置元素");

  const { couponCode, popupHeadline, minimumCartValue, enablePopup } =
    config.dataset;

  // 如果禁用则提前退出(在模块作用域使用throw,不要用return)
  if (enablePopup !== "true") {
    throw new Error("弹窗已禁用");
  }

  // 主逻辑在函数中(此处允许使用return)
  async function initializePopup() {
    const minValue = Number(minimumCartValue) || 0;
    // ... 弹窗实现代码
  }

  // DOM准备就绪时初始化
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initializePopup);
  } else {
    initializePopup();
  }
</script>

3. Dashboard Page (See
wix-cli-dashboard-page
skill)

3. 仪表板页面(参见
wix-cli-dashboard-page
技能)

Uses
embeddedScripts
API from
@wix/app-management
:
typescript
import { embeddedScripts } from "@wix/app-management";

// Load parameters
const script = await embeddedScripts.getEmbeddedScript();
const params = script.parameters; // { couponCode: "...", ... }

// Save parameters (all values must be strings)
await embeddedScripts.embedScript({
  parameters: {
    couponCode: "SAVE20",
    minimumCartValue: "50", // Number as string
    enablePopup: "true", // Boolean as string
  },
});
使用
@wix/app-management
中的
embeddedScripts
API:
typescript
import { embeddedScripts } from "@wix/app-management";

// 加载参数
const script = await embeddedScripts.getEmbeddedScript();
const params = script.parameters; // { couponCode: "...", ... }

// 保存参数(所有值必须是字符串)
await embeddedScripts.embedScript({
  parameters: {
    couponCode: "SAVE20",
    minimumCartValue: "50", // 数值以字符串形式存储
    enablePopup: "true", // 布尔值以字符串形式存储
  },
});

Extension Registration

扩展注册

Extension registration is MANDATORY and has TWO required steps.
扩展注册是强制性的,需要两个步骤。

Step 1: Create Script-Specific Extension File

步骤1:创建脚本专属扩展文件

Each embedded script requires an
extensions.ts
file in its folder:
typescript
import { extensions } from "@wix/astro/builders";

export const embeddedscriptMyScript = extensions.embeddedScript({
  id: "{{GENERATE_UUID}}",
  name: "My Script",
  source: "./site/embedded-scripts/my-script/embedded.html",
  placement: "BODY_END",
  scriptType: "FUNCTIONAL",
});
CRITICAL: UUID Generation
The
id
must be a unique, static UUID v4 string. Generate a fresh UUID for each extension - do NOT use
randomUUID()
or copy UUIDs from examples. Replace
{{GENERATE_UUID}}
with a freshly generated UUID like
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
.
PropertyTypeDescription
id
stringUnique static UUID v4 (generate fresh)
name
stringDisplay name for the script
source
stringRelative path to the HTML file
placement
enum
HEAD
,
BODY_START
, or
BODY_END
scriptType
enum
ESSENTIAL
,
FUNCTIONAL
,
ANALYTICS
,
ADVERTISING
每个嵌入式脚本在其文件夹中需要一个
extensions.ts
文件:
typescript
import { extensions } from "@wix/astro/builders";

export const embeddedscriptMyScript = extensions.embeddedScript({
  id: "{{GENERATE_UUID}}",
  name: "My Script",
  source: "./site/embedded-scripts/my-script/embedded.html",
  placement: "BODY_END",
  scriptType: "FUNCTIONAL",
});
关键:UUID生成
id
必须是唯一的静态UUID v4字符串。为每个扩展生成新的UUID - 不要使用
randomUUID()
或复制示例中的UUID。将
{{GENERATE_UUID}}
替换为新生成的UUID,例如
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
属性类型描述
id
string唯一的静态UUID v4(需新生成)
name
string脚本的显示名称
source
stringHTML文件的相对路径
placement
枚举
HEAD
BODY_START
BODY_END
scriptType
枚举
ESSENTIAL
FUNCTIONAL
ANALYTICS
ADVERTISING

Step 2: Register in Main Extensions File

步骤2:在主扩展文件中注册

CRITICAL: After creating the script-specific extension file, you MUST read wix-cli-extension-registration and follow the "App Registration" section to update
src/extensions.ts
.
Without completing Step 2, the embedded script will not be deployed to the site.
关键: 创建脚本专属扩展文件后,必须阅读wix-cli-extension-registration并按照“应用注册”部分的说明更新
src/extensions.ts
如果不完成步骤2,嵌入式脚本将不会部署到网站。

Enable Embedded Script Permission

启用嵌入式脚本权限

After implementation, the app developer must manually enable the embedded script permission:
  1. Go to https://manage.wix.com/apps/{app-id}/dev-center-permissions (replace
    {app-id}
    with your actual app ID)
  2. Add the
    APPS.MANAGE_EMBEDDED_SCRIPT
    permission
  3. Save the changes
Note: This is a manual step in the Wix Dev Center. Without this permission, embedded scripts will not function on the site.
实现完成后,应用开发者必须手动启用嵌入式脚本权限:
  1. 访问https://manage.wix.com/apps/{app-id}/dev-center-permissions(将
    {app-id}
    替换为你的实际应用ID)
  2. 添加
    APPS.MANAGE_EMBEDDED_SCRIPT
    权限
  3. 保存更改
注意: 这是Wix开发者中心中的手动步骤。没有此权限,嵌入式脚本将无法在网站上运行。

Verification

验证

After implementation, use wix-cli-app-validation to validate TypeScript compilation, build, preview, and runtime behavior.
实现完成后,使用wix-cli-app-validation验证TypeScript编译、构建、预览和运行时行为。