Appearance
Are you an LLM? You can read better optimized documentation at /docs/custom-widgets/v2/scripts.md for this page in Markdown format
Script Definition Reference
This page documents every field of a script entry in the scripts array of extensions_registry.json. For the root of the registry file, see Registry Reference. For the mental model of how scripts run, see Scripts Overview.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier for the asset. Must start with a letter or number; can include letters, numbers, _, ., -. |
path | string | Yes | Path to the asset file — either a relative path within the repository or an external URL (https://...). |
description | string | No | Brief description of what the asset does. |
placement | string | No | Where the asset is injected on the page: head, bodyStart, or bodyEnd. Defaults to head. |
attributes | object | No | HTML attributes to add to the generated tag (e.g., defer, async, crossorigin). See HTML Attributes below. |
rules | array | No | Condition rules controlling which pages the asset loads on. |
Placement
| Value | Location | Use case |
|---|---|---|
head (default) | Inside <head> | Analytics, early initialization, fonts, and styles that must apply before content renders |
bodyStart | Start of <body> | Assets that need the DOM to start loading but should run early |
bodyEnd | End of <body> | Non-critical assets that depend on page content being fully loaded |
Scripts must have a path ending in .js.
Repository-Hosted Scripts
For scripts stored in your repository, use a relative path. The platform publishes the file automatically.
Place each script in its own directory: scripts/<name>/script.js
json
{
"scripts": [
{
"name": "analytics",
"path": "scripts/analytics/script.js",
"description": "Tracks widget impressions and interactions",
"placement": "head"
}
]
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
External Scripts
If path is an external URL, the script is loaded directly from that URL — it is not published by the platform.
json
{
"scripts": [
{
"name": "external-tracker",
"path": "https://cdn.example.com/tracker.js",
"description": "Third-party event tracking",
"placement": "bodyEnd"
}
]
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
HTML Attributes
Use the attributes field to add standard HTML attributes to the generated <script> tag. This gives you control over script loading behavior and execution timing.
json
{
"scripts": [
{
"name": "analytics",
"path": "scripts/analytics/script.js",
"placement": "head",
"attributes": {
"defer": ""
}
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
This produces: <script src="..." defer></script>
The attributes field is a plain object where each key is the attribute name and the value is the attribute value. Use an empty string ("") for boolean attributes like defer and async.
Common Attributes
| Attribute | Value | Effect |
|---|---|---|
defer | "" | Script executes after HTML parsing completes — does not block page rendering |
async | "" | Script downloads in parallel and executes as soon as it's ready |
crossorigin | "anonymous" | Enables CORS requests without sending credentials |
crossorigin | "use-credentials" | Enables CORS requests with credentials |
When to Use defer
Use defer when your script depends on the DOM being fully parsed but should not block the initial page render. This is the most common use case for custom scripts — analytics, tracking, and UI enhancements that run after the page loads.
json
{
"scripts": [
{
"name": "post-render-init",
"path": "scripts/init/script.js",
"placement": "head",
"attributes": {
"defer": ""
}
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
defer vs placement
defer and placement serve different purposes. placement controls where in the HTML the <script> tag appears. defer controls when the script executes — always after parsing, regardless of placement. For most non-blocking scripts, "placement": "head" with "defer": "" is the recommended approach.
Multiple Attributes
You can combine multiple attributes on a single script:
json
{
"attributes": {
"defer": "",
"crossorigin": "anonymous"
}
}1
2
3
4
5
6
2
3
4
5
6
This produces: <script src="..." defer crossorigin="anonymous"></script>
Conditional Loading
Use rules to control which pages a script loads on. Without rules, the script loads on every page. See Page Targeting for the full rules reference.
json
{
"scripts": [
{
"name": "homepage-hero",
"path": "scripts/hero/script.js",
"rules": [
{ "field": "page", "operator": "eq", "value": "homepage" }
]
},
{
"name": "user-analytics",
"path": "scripts/analytics/script.js",
"rules": [
{ "field": "authenticated", "operator": "eq", "value": "true" }
]
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Validation
namemust match^[a-zA-Z0-9][a-zA-Z0-9_.-]*$namemust be unique within thescriptsarraypathmust end in.js— either a relative path or a URL starting withhttp://orhttps://placementmust be one ofhead,bodyStart,bodyEndrulesmust follow the condition rules schema
Next Steps
- Scripts Overview — mental model for how scripts are injected
- Your First Script — hands-on tutorial
- Stylesheet Definition Reference — Add global CSS to your community
- Page Targeting — Full context field reference for conditional loading
- Registry Reference — the root of
extensions_registry.json - Repository Layout — How to organize your repository
- Analytics script in the template repository — Working global script example

