# Configuration



When the OptinStack script loads, it fetches your published project configuration and exposes the resolved result through the public `window.OptinStack` API. You do not configure the runtime by editing data on the page; you configure it in the dashboard, and the script applies it automatically.

<Callout type="info">
  Configuration is managed in the OptinStack dashboard. The reference below describes the shape of what the runtime
  applies, useful when reading `window.OptinStack.config` for debugging or custom integrations.
</Callout>

Published configuration is hostname-aware. Webflow, Framer, and custom sites use the same entitlement rules—platform choice never elevates features. Free can activate on each eligible hostname by default. A paid subscription attaches to one hostname and can move once to a registered, verified production hostname. Unassigned registered hostnames do not publish or serve runtime configuration. See [Domain Scans](/domain-scans) for details.

## `window.OptinStack.config` [#windowoptinstackconfig]

After `await window.OptinStack.ready`, the resolved configuration is available read-only:

| Property        | Type     | Description                                                              |
| --------------- | -------- | ------------------------------------------------------------------------ |
| `config.site`   | `object` | Your published site config: policies, trackers, presentation, compliance |
| `config.policy` | `object` | The consent policy matched for the current visitor's region              |

### `config.site` sections [#configsite-sections]

| Section        | Description                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| `identity`     | `siteId` (project ID) and `revision` (config version)                                                         |
| `scope`        | Page targeting (`pages: '*'` or path list)                                                                    |
| `policy`       | Consent policies, categories, GPC signals, renewal settings                                                   |
| `inventory`    | Tracker list for blocking and preferences UI                                                                  |
| `presentation` | Theme, legal links, locale strings, interaction (scroll lock), vendor list                                    |
| `compliance`   | Reserved compliance configuration. OptinStack is not currently an IAB TCF CMP and does not expose `__tcfapi`. |

### `scope.pages` (page targeting) [#scopepages-page-targeting]

Control which paths show the banner and enforce consent UI:

| Value           | Behavior                                                       |
| --------------- | -------------------------------------------------------------- |
| `'*'` (default) | All pages                                                      |
| Path list       | Only matching pathnames (for example `['/shop', '/checkout']`) |

Off-target pages still load the runtime for API access, but the banner is not shown for that visit. Configure targeting in the dashboard.

### `policy.policies[]` [#policypolicies]

Each policy defines region-specific consent behavior:

| Property        | Type                                                      | Description                                               |
| --------------- | --------------------------------------------------------- | --------------------------------------------------------- |
| `id`            | `string`                                                  | Stable policy identifier (e.g. `'opt-in'`, `'dont-sell'`) |
| `consentModel`  | `'opt-in' \| 'opt-out' \| 'informational'`                | Consent **model** (defaults and decision semantics)       |
| `uiVariant`     | `'opt-in' \| 'opt-out' \| 'informational' \| 'dont-sell'` | Banner **UI** (includes Do Not Sell presentation)         |
| `scope.regions` | `string[]`                                                | ISO region codes or `'global'` / `'eu'`                   |

At runtime, `window.OptinStack.mode` reflects `consentModel` and `window.OptinStack.uiVariant` reflects `uiVariant`.

### `policy.renewal` [#policyrenewal]

| Property                | Type                 | Description                             |
| ----------------------- | -------------------- | --------------------------------------- |
| `promptOnExpiry`        | `boolean` (optional) | Re-show the banner when consent expires |
| `ttlDays`               | `number`             | Consent cookie expiration in days       |
| `shareAcrossSubdomains` | `boolean`            | Share consent across subdomains         |
| `record.secure`         | `boolean`            | Require HTTPS for consent cookies       |

See [Consent Cookie](/consent-cookie) for the stored cookie format and how `shareAcrossSubdomains` affects subdomain access.

### `presentation.locale` and languages [#presentationlocale-and-languages]

English is the fixed source language. You can enable secondary locales from the dashboard (23 languages total, including English). Locale strings power banner and preferences copy. The runtime resolves the visitor language from `html lang` (then falls back to English when a locale is not enabled). Language packs are generated on publish and loaded from the CDN, not as a separate script install. Need a language that is not listed? [Contact us](https://optinstack.com/contact) to request it.

### `presentation.interaction.scrollLock` [#presentationinteractionscrolllock]

Optional background scroll lock while the banner or preferences UI is open (`both`, `banner`, `preferences`, or off depending on dashboard settings). Configure this in the dashboard; read it from `config.site.presentation` only for debugging.

### Vendors [#vendors]

Vendor / provider definitions used by preferences and the tracker declaration appear under presentation (for example `presentation.vendors` / providers). They are managed from your tracker inventory and provider metadata in the dashboard.

## Policy matching [#policy-matching]

The runtime evaluates policies in this priority order:

1. **Region match**: a policy whose `scope.regions` contains the visitor's detected region
2. **EU match**: if the visitor is in the EU and a policy includes `'eu'`
3. **Global fallback**: a policy with `'global'` in `scope.regions`

Projects with region rules use the most specific matching policy available. Projects without region-specific rules fall back to the global policy.

<Callout type="info">
  Regional rules and geo-targeted banner behavior require a plan that includes geo-targeting. Projects without that
  entitlement use the published global policy.
</Callout>

## When configuration takes effect [#when-configuration-takes-effect]

Changes you make in the dashboard apply to new visits after you publish. Existing visitors keep their stored consent until it expires or they change it.
