--- url: https://developer-portal.gainsight.com/docs/custom-widgets/v2/scripts.md description: >- Reference for script entries in the scripts array of extensions_registry.json — fields, placement, HTML attributes, and validation rules --- # 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](registry-reference). For the mental model of how scripts run, see [Scripts Overview](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](#html-attributes) below. | | `rules` | array | No | [Condition rules](/custom-widgets/v2/page-targeting) controlling which pages the asset loads on. | ## Placement | Value | Location | Use case | |-------|----------|----------| | `head` (default) | Inside `` | Analytics, early initialization, fonts, and styles that must apply before content renders | | `bodyStart` | Start of `` | Assets that need the DOM to start loading but should run early | | `bodyEnd` | End of `` | 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//script.js` ```json { "scripts": [ { "name": "analytics", "path": "scripts/analytics/script.js", "description": "Tracks widget impressions and interactions", "placement": "head" } ] } ``` ## 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" } ] } ``` ## HTML Attributes Use the `attributes` field to add standard HTML attributes to the generated `` 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": "" } } ] } ``` ::: tip defer vs placement `defer` and `placement` serve different purposes. `placement` controls **where** in the HTML the `` ## Conditional Loading Use `rules` to control which pages a script loads on. Without rules, the script loads on every page. See [Page Targeting](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" } ] } ] } ``` ## Validation * `name` must match `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$` * `name` must be unique within the `scripts` array * `path` must end in `.js` — either a relative path or a URL starting with `http://` or `https://` * `placement` must be one of `head`, `bodyStart`, `bodyEnd` * `rules` must follow the [condition rules schema](page-targeting#rule-structure) ## Next Steps * [Scripts Overview](scripts-overview) — mental model for how scripts are injected * [Your First Script](first-script) — hands-on tutorial * [Stylesheet Definition Reference](stylesheets) — Add global CSS to your community * [Page Targeting](page-targeting) — Full context field reference for conditional loading * [Registry Reference](registry-reference) — the root of `extensions_registry.json` * [Repository Layout](project-setup) — How to organize your repository * [Analytics script in the template repository](https://github.com/gainsight-hub/widgets-repository-template/blob/main/scripts/analytics/script.js) — Working global script example