# Custom Scripts

Add custom JavaScript snippets to your documentation site for analytics, widgets, or any custom functionality not covered by built-in integrations.

Inject custom JavaScript into your published documentation site. Use custom scripts for analytics providers not covered by [built-in integrations](/content/docs/integrations/overview/index.html), consent banners, A/B testing tools, or any custom functionality.

## Prerequisites

- A documentation project with publishing access
- A `.js` or `.mjs` script file added to your documentation project

## Configure custom scripts from the Editor

You can manage custom scripts directly from the Editor without editing JSON.

Open Site Config

In the Editor, click **Site Config** in the top toolbar.

Navigate to Custom Scripts

Select **Custom Scripts** from the left sidebar.

Add a script

Click **Add Script** and select the script file from your project. Only `.js` and `.mjs` files are available for selection.

Publish

Click **Publish** to deploy the script to your live site. Custom script changes appear in the **Changes** panel alongside content edits.

## Configure custom scripts via documentation.json

If you manage configuration in version control, add scripts directly to `documentation.json`:

```
{
  "scripts": [
    { "src": "scripts/consent-banner.js" },
    { "src": "scripts/custom-tracking.mjs" }
  ]
}
```

Each entry in the `scripts` array supports the following properties:

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `src` | string | Yes | Relative file path to a `.js` or `.mjs` file in your project, or an external URL |
| `category` | string | No | Consent category name matching a key in `integrations.cookies`. Defaults to `essential` (always loads). See [Cookie Consent](/content/docs/customize/site-configuration#cookie-consent/index.html). |

### Script file requirements

- Files must use a `.js` or `.mjs` extension.
- Paths are relative to your project root (for example, `scripts/analytics.js`).
- Maximum file size is 5 MB.
- The file must exist in your documentation project before you can reference it.
- External URLs must use **HTTPS**.

Script paths must be relative; no leading `/`, `./`, or `../`. Path traversal patterns are rejected for security.

### External scripts

You can also reference scripts hosted on external CDNs or third-party services:

```
{
  "scripts": [
    { "src": "https://cdn.example.com/widget.js", "category": "marketing" }
  ]
}
```

External URLs must use HTTPS. The same `category` consent gating applies to external scripts.

## Consent category behavior

When you configure [cookie consent](/content/docs/customize/cookie-consent/index.html) categories in your `integrations.cookies` settings, scripts respect the following rules:

| Scenario | Behavior |
| --- | --- |
| Script has `category: "essential"` or no category set | Always loads regardless of consent state |
| Script category matches a configured consent category | Loads only after the user grants consent for that category |
| Script category is not defined in `integrations.cookies` | Loads by default (only explicitly configured categories are gated) |
| User revokes consent after granting it | Script stops loading on subsequent page navigations |

Scripts react to consent changes in real time. If a user updates their cookie preferences, gated scripts load or stop loading without requiring a full page refresh.

If you want a script to always run regardless of consent settings, either set its category to `"essential"` or omit the `category` field entirely.

## Loading behavior

Custom scripts load using a non-blocking strategy after the page becomes interactive. This means:

- Scripts do not block initial page rendering or content display
- Scripts execute after the main document content loads and hydrates
- Multiple scripts load in the order defined in the `scripts` array
- Local scripts are served from a secure CDN with aggressive caching (30-day TTL)

This ensures your documentation pages remain fast for readers even when multiple custom scripts are configured.

## Security considerations

Custom scripts execute in your readers' browsers with full page access.

- Only add scripts you trust and have reviewed.
- Audit script contents periodically, especially if they interact with user data or external services.

Malicious or misconfigured scripts can break your documentation site or compromise reader privacy. Test scripts in a staging environment before publishing to production.

## Troubleshooting

**Script not loading**: Verify the file exists in your project and uses a `.js` or `.mjs` extension. Check the browser developer console for syntax errors.

**Script conflicts**: If multiple scripts interfere with each other, try reordering them in the scripts array. Scripts load in the order they appear in the configuration.

**Changes not visible**: Custom script changes require publishing. Check that you have published after making edits.

## What's next

- [Cookie Consent](/content/docs/customize/cookie-consent/index.html) - gate scripts behind user consent for GDPR compliance
- [Analytics and chat integrations](/content/docs/integrations/overview/index.html) - zero-code setup for popular analytics and chat tools
- [Site configuration reference](/content/docs/customize/site-configuration/index.html) - full `documentation.json` reference
