npx skills add https://github.com/wix/skills --skill wix-cli-embedded-script为 Wix CLI 应用程序创建嵌入式脚本扩展。嵌入式脚本是注入到 Wix 网站 DOM 中的 HTML 代码片段,可实现与第三方服务的集成、分析跟踪、广告投放和自定义 JavaScript 功能。
创建嵌入式脚本时,请按顺序遵循以下步骤:
src/extensions/site/embedded-scripts/<script-name>/embedded.htmlextensions.embeddedScript() 和唯一 UUID 创建 extensions.tssrc/extensions/dashboard/pages/<script-name>-settings/@wix/app-management 的 embeddedScripts API 实现配置页面src/extensions.ts 以导入和使用这两个扩展广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
SCOPE.DC-APPS.MANAGE-EMBEDDED-SCRIPTS 权限(参见启用嵌入式脚本权限)嵌入式脚本必须为同意管理声明一个类型:
| 类型 | 描述 | 用例 |
|---|---|---|
ESSENTIAL | 对网站运行至关重要的核心功能 | 身份验证、安全功能 |
FUNCTIONAL | 记住用户选择以改善体验 | 语言偏好、UI 自定义 |
ANALYTICS | 提供有关访问者如何使用网站的统计数据 | Google Analytics、Hotjar、Mixpanel |
ADVERTISING | 为营销目的提供访问者数据 | Facebook Pixel、Google Ads、再营销 |
选择规则: 如果一个脚本属于多种类型,请选择列表中最靠下的选项(限制性最强)。例如,同时具有分析和广告属性的脚本应归类为 ADVERTISING。
| 放置位置 | 描述 | 最适合 |
|---|---|---|
HEAD | 在 <head> 和 </head> 标签之间 | 分析、早期初始化 |
BODY_START | 紧接在打开的 <body> 标签之后 | 关键功能、noscript |
BODY_END | 紧接在关闭的 </body> 标签之前 | 非阻塞脚本、性能 |
选择指南:
HEAD(尽早初始化)BODY_END(非阻塞)HEAD 或 BODY_STARTBODY_END(更好的性能)每个嵌入式脚本都需要一个配套的仪表板页面 来配置其参数。网站所有者使用仪表板页面 UI 设置值,然后这些值作为模板变量传递给嵌入式脚本。
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
相关技能: 使用 wix-cli-dashboard-page 为您的嵌入式脚本创建配置 UI。
| 类型 | 描述 | 仪表板组件 |
|---|---|---|
TEXT | 单行文本 | Input |
NUMBER | 数值 | Input type="number" |
BOOLEAN | 真/假切换 | ToggleSwitch、Checkbox |
IMAGE | 来自媒体管理器的图像 | ImagePicker |
DATE | 仅日期 | DatePicker |
DATETIME | 包含时间的日期 | DatePicker + TimeInput |
URL | 经过验证的 URL | Input |
SELECT | 下拉选项 | Dropdown |
COLOR | 颜色值 | ColorPicker |
嵌入式脚本支持使用模板变量语法 {{variableName}} 进行参数化。这些参数通过仪表板配置,并作为模板变量传递,应在您的 HTML/JavaScript 代码中使用。
使用说明:
模板变量语法:
{{parameterKey}} 语法将参数值插入到您的 HTML 中HTML 属性(必需):
<div id="config" data-headline="{{headline}}" data-text="{{text}}"></div>JavaScript 访问:
JavaScript 必须从 data 属性中读取参数值
使用 getAttribute() 或 dataset 属性
示例:
const config = document.getElementById("config");
const headline = config?.getAttribute("data-headline");
// 或者使用 dataset:
const { headline, text } = config.dataset;
类型安全:
Number() 或 parseInt() 转换'true' 或 'false' 进行比较new Date() 解析必需与可选:
相关参数使用:
示例模式:
模式 1 - Data 属性中的配置:
<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 属性:
<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 - 条件逻辑:
<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}} 必须与参数定义中的确切键名匹配每个嵌入式脚本至少应具有一个启用/禁用切换参数:
| 参数 | 类型 | 用途 |
|---|---|---|
enabled | BOOLEAN | 允许网站所有者激活/禁用 |
apiKey | TEXT | 第三方服务凭据 |
trackingId | TEXT | 分析/像素标识符 |
headline | TEXT | 可自定义的显示文本 |
color | COLOR | UI 自定义 |
一个完整的嵌入式脚本实现需要两个部分:
src/extensions/site/embedded-scripts/
└── {script-name}/
├── embedded.html # 要注入的 HTML/JavaScript 代码
└── extensions.ts # 元数据(scriptType、placement)
src/extensions/dashboard/
├── withProviders.tsx # WDS 提供者包装器(必需)
└── pages/
└── {script-name}-settings/
├── extensions.ts # 扩展注册(必需)
└── page.tsx # 使用 embeddedScripts API 的配置 UI
注意: 仪表板页面需要其自己的 extensions.ts 文件。没有此文件,仪表板页面将不会出现在 Wix 仪表板中。
警告: 仪表板页面使用的字段名称与嵌入式脚本不同:
title、routePath、componentname、source、placement、scriptType请勿将嵌入式脚本的字段名称应用于仪表板页面注册。
参见 wix-cli-dashboard-page 技能 以获取仪表板页面实现细节和扩展注册模式。
<!-- 包含模板变量的配置元素 -->
<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("Config element not found");
const { apiKey, enabled } = config.dataset;
// 如果禁用则提前退出(在模块作用域使用 throw,而不是 return)
if (enabled !== "true") {
throw new Error("Script disabled");
}
// 在命名函数中实现功能(此处允许使用 return)
async function initialize() {
try {
// 您的实现
} catch (error) {
console.error("Script error:", error);
}
}
// 当 DOM 准备就绪时初始化
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initialize);
} else {
initialize();
}
</script>
请求: "为我的网站添加 Google Analytics 跟踪"
输出:
ANALYTICSHEAD{{trackingId}}请求: "创建一个当购物车价值超过 50 美元时显示的优惠券弹窗"
输出:
FUNCTIONALBODY_END{{couponCode}}、{{minimumCartValue}}、{{enablePopup}}请求: "集成 Intercom 聊天小部件"
输出:
FUNCTIONALBODY_END{{appId}}、{{userEmail}}、{{userName}}throw new Error() 进行提前退出,而不是 return。Rollup(由 Astro 使用)不允许在模块作用域使用 return 语句。将主要逻辑包装在允许使用 return 的命名异步函数中。/api/* 端点的 fetch() 调用"cart-coupon-popup" 的参数:
- couponCode (TEXT, required) - 要显示的优惠券代码
- popupHeadline (TEXT, required) - 标题文本
- popupDescription (TEXT, required) - 描述文本
- minimumCartValue (NUMBER) - 显示弹窗的最低购物车价值
- enablePopup (BOOLEAN, required) - 启用/禁用切换
embedded.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("Config element not found");
const { couponCode, popupHeadline, minimumCartValue, enablePopup } =
config.dataset;
// 如果禁用则提前退出(在模块作用域使用 throw,而不是 return)
if (enablePopup !== "true") {
throw new Error("Popup disabled");
}
// 在函数中的主要逻辑(此处允许使用 return)
async function initializePopup() {
const minValue = Number(minimumCartValue) || 0;
// ... 弹窗实现
}
// 当 DOM 准备就绪时初始化
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initializePopup);
} else {
initializePopup();
}
</script>
wix-cli-dashboard-page 技能)使用来自 @wix/app-management 的 embeddedScripts API:
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", // 布尔值作为字符串
},
});
扩展注册是强制性的,并且需要两个步骤。
每个嵌入式脚本都需要在其文件夹中有一个 extensions.ts 文件:
import { extensions } from "@wix/astro/builders";
export const embeddedscriptMyScript = extensions.embeddedScript({
id: "{{GENERATE_UUID}}",
name: "My Script",
source: "./extensions/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 | string | 到 HTML 文件的相对路径 |
placement | enum | HEAD、BODY_START 或 BODY_END |
scriptType | enum | ESSENTIAL、FUNCTIONAL、ANALYTICS、ADVERTISING |
关键: 创建脚本特定的扩展文件后,您必须阅读 wix-cli-extension-registration 并按照"应用注册"部分更新 src/extensions.ts。
如果不完成步骤 2,嵌入式脚本将不会部署到网站。
实现后,应用开发者必须手动启用嵌入式脚本权限:
{app-id} 替换为您的实际应用 ID)SCOPE.DC-APPS.MANAGE-EMBEDDED-SCRIPTS 权限注意: 这是 Wix 开发者中心中的一个手动步骤。没有此权限,嵌入式脚本将无法在网站上运行。
每周安装次数
195
仓库
GitHub 星标数
3
首次出现
2026年1月26日
安全审计
安装于
opencode173
cursor94
codex89
gemini-cli87
github-copilot84
kimi-cli79
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.
Follow these steps in order when creating an embedded script:
src/extensions/site/embedded-scripts/<script-name>/embedded.html with config element, styles, and script logicextensions.ts with extensions.embeddedScript() and unique UUIDsrc/extensions/dashboard/pages/<script-name>-settings/embeddedScripts API from @wix/app-managementsrc/extensions.ts to import and use both extensionsSCOPE.DC-APPS.MANAGE-EMBEDDED-SCRIPTS permission in the Wix Dev Center (see Enable Embedded Script Permission)Embedded scripts must declare a type for consent management:
| Type | Description | Use Cases |
|---|---|---|
ESSENTIAL | Core functionality crucial to site operation | Authentication, security features |
FUNCTIONAL | Remembers user choices to improve experience | Language preferences, UI customization |
ANALYTICS | Provides statistics on how visitors use the site | Google Analytics, Hotjar, Mixpanel |
ADVERTISING | Provides visitor data for marketing purposes | Facebook 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.
| Placement | Description | Best 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 |
Selection guidelines:
HEAD (initialize early)BODY_END (non-blocking)HEAD or BODY_STARTBODY_END (better performance)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.
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.
| Type | Description | Dashboard Component |
|---|---|---|
TEXT | Single-line text | Input |
NUMBER | Numeric value | Input type="number" |
BOOLEAN | True/false toggle | ToggleSwitch, Checkbox |
IMAGE | Image from media manager | ImagePicker |
DATE | Date only | DatePicker |
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:
Template Variable Syntax:
{{parameterKey}} syntax to insert parameter values into your HTMLHTML Attributes (REQUIRED):
<div id="config" data-headline="{{headline}}" data-text="{{text}}"></div>JavaScript Access:
JavaScript must read parameter values from the data attributes
Use getAttribute() or the dataset property
Examples:
const config = document.getElementById("config");
const headline = config?.getAttribute("data-headline");
// OR using dataset:
const { headline, text } = config.dataset;
Example Patterns:
Pattern 1 - Configuration in Data Attributes:
<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:
<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:
<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:
{{parameterKey}} must match the exact key names from the parameter definitionsEvery embedded script should have at minimum an enable/disable toggle parameter:
| Parameter | Type | Purpose |
|---|---|---|
enabled | BOOLEAN | Allow site owner to activate/disable |
apiKey | TEXT | Third-party service credentials |
trackingId | TEXT | Analytics/pixel identifiers |
headline |
A complete embedded script implementation requires two parts :
src/extensions/site/embedded-scripts/
└── {script-name}/
├── embedded.html # HTML/JavaScript code to inject
└── extensions.ts # Metadata (scriptType, placement)
src/extensions/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:
title, routePath, componentname, source, placement, scriptTypeDo NOT apply embedded script field names to dashboard page registrations.
Seewix-cli-dashboard-page skill for dashboard page implementation details and the extension registration pattern.
<!-- 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>
Request: "Add Google Analytics tracking to my site"
Output:
ANALYTICSHEAD{{trackingId}}Request: "Create a coupon popup that shows when cart value exceeds $50"
Output:
FUNCTIONALBODY_END{{couponCode}}, {{minimumCartValue}}, {{enablePopup}}Request: "Integrate Intercom chat widget"
Output:
FUNCTIONALBODY_END{{appId}}, {{userEmail}}, {{userName}}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.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
embedded.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>
wix-cli-dashboard-page skill)Uses embeddedScripts API from @wix/app-management:
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
},
});
Extension registration is MANDATORY and has TWO required steps.
Each embedded script requires an extensions.ts file in its folder:
import { extensions } from "@wix/astro/builders";
export const embeddedscriptMyScript = extensions.embeddedScript({
id: "{{GENERATE_UUID}}",
name: "My Script",
source: "./extensions/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".
| Property | Type | Description |
|---|---|---|
id | string | Unique static UUID v4 (generate fresh) |
name | string | Display name for the script |
source | string | Relative path to the HTML file |
placement | enum | HEAD, BODY_START, or |
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.
After implementation, the app developer must manually enable the embedded script permission:
{app-id} with your actual app ID)SCOPE.DC-APPS.MANAGE-EMBEDDED-SCRIPTS permissionNote: This is a manual step in the Wix Dev Center. Without this permission, embedded scripts will not function on the site.
Weekly Installs
195
Repository
GitHub Stars
3
First Seen
Jan 26, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode173
cursor94
codex89
gemini-cli87
github-copilot84
kimi-cli79
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
111,800 周安装
| Non-blocking scripts, performance |
DATETIME | Date with time | DatePicker + TimeInput |
URL | URL with validation | Input |
SELECT | Dropdown options | Dropdown |
COLOR | Color value | ColorPicker |
Type Safety:
Number() or parseInt()'true' or 'false' stringsnew Date()Required vs Optional:
Relevant Parameter Usage:
TEXT |
| Customizable display text |
color | COLOR | UI customization |
BODY_ENDscriptType | enum | ESSENTIAL, FUNCTIONAL, ANALYTICS, ADVERTISING |