# Install



OptinStack is added to your site with a single `<script>` tag placed as the first element inside your page's `<head>`. The tag loads the consent runtime, which fetches your project configuration and renders the consent banner.

The dashboard generates the correct snippet on the [Implementation](https://app.optinstack.com) page, so you do not need to build the tag by hand.

Install the snippet on every hostname where you want the banner to run. For production, that must be the **exact** public hostname visitors see in the address bar (including `www` when that is the live host). Development hostnames are useful while building—activate Free or paid there while you test, then activate Free or move a paid plan on your verified production hostname when ready. See [Domain Scans](/domain-scans) for hostname, license, and reverse-proxy guidance.

## Script tag [#script-tag]

The script points at a stable URL that serves the current runtime, so your install receives runtime and compliance updates automatically with no maintenance.

```html
<script
  src="https://api.optinstack.com/v1/js/runtime/stable/optinstack.js"
  data-optinstack-site="{projectId}"
></script>
```

Do not add `async` or `defer` to the OptinStack tag. The browser pauses HTML parsing while a plain script executes, which gives the runtime its earliest chance to load configuration and install blocking before later third-party tags run.

## Attributes [#attributes]

| Attribute              | Required | Description                                                                            |
| ---------------------- | -------- | -------------------------------------------------------------------------------------- |
| `src`                  | Yes      | Runtime URL. Use `https://api.optinstack.com/v1/js/runtime/stable/optinstack.js`.      |
| `data-optinstack-site` | Yes      | Your project ID from the dashboard. Links the install to your published configuration. |

Replace `{projectId}` with the value from your dashboard. The dashboard snippet always contains the correct value.

## Pinned runtime with SRI [#pinned-runtime-with-sri]

Every project can use a pinned runtime version with Subresource Integrity. Pinned installs trade automatic runtime hotfixes for a reviewable, immutable script URL and a browser-enforced integrity hash.

```html
<script
  src="https://api.optinstack.com/v1/js/runtime/{version}/optinstack.js"
  integrity="{optinstack_sri}"
  crossorigin="anonymous"
  data-optinstack-site="{projectId}"
></script>
```

Banner configuration, tracker inventory, region context, and translations continue to load as JSON data, so publishing banner copy or translations does not change the pinned runtime bytes. To receive runtime code updates, select a newer pinned version in the dashboard.

## Where the script goes [#where-the-script-goes]

Add the tag as the **first child** of `<head>`, before any third-party scripts or iframes you want consent to govern:

```html title="index.html"
<!DOCTYPE html>
<html>
  <head>
    <!-- OptinStack: first, before trackers -->
    <script
      src="https://api.optinstack.com/v1/js/runtime/stable/optinstack.js"
      data-optinstack-site="{projectId}"
    ></script>

    <!-- Third-party scripts below -->
    <script src="https://www.googletagmanager.com/gtag/js"></script>
    <link rel="stylesheet" href="/styles.css" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>
```

Placing it first lets OptinStack block known trackers from your published inventory, plus resources you manually tag with `data-optinstack-categories`, before those resources load. Unknown untagged resources are not universally blocked until they are scanned, classified, manually added, or tagged. If a tag manager or platform injects trackers above OptinStack, those resources can run before consent enforcement is available.

## Content Security Policy (CSP) [#content-security-policy-csp]

If your site uses a strict CSP, allow OptinStack to load the runtime and fetch configuration from the OptinStack API origin used in your install (production: `https://api.optinstack.com`). Typical requirements:

| Directive                  | Why                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| `script-src`               | Load `optinstack.js` (and `banner.js` when the runtime loads the UI bundle)                      |
| `connect-src`              | Fetch published configuration, record consent, and related runtime API calls                     |
| `style-src` / font sources | Banner UI may inject styles and load fonts from the API origin                                   |
| `frame-src` / `child-src`  | Only if you embed OptinStack-related iframes or blocked-iframe placeholders interact with frames |

Exact values depend on your CSP style (`'self'`, nonces, hashes). Prefer allowing the documented API host rather than open wildcards. After changing CSP, verify the banner appears, consent records, and Google tags still receive Consent Mode updates.

## Manual category tagging [#manual-category-tagging]

Use `data-optinstack-categories` when you need to govern a custom script or iframe before it appears in your tracker inventory. The value is a comma-separated list of consent categories. The runtime blocks the resource until every listed category is granted.

```html
<script src="https://analytics.example.com/tracker.js" data-optinstack-categories="analytics"></script>

<iframe src="https://video.example.com/embed/123" data-optinstack-categories="marketing,preferences"></iframe>
```

Supported optional categories are `analytics`, `marketing`, and `preferences`. The `necessary` category is always allowed and should only be used for resources that are essential to the site.

## Next steps [#next-steps]

<Cards>
  <Card title="Getting started" href="/getting-started">
    Verify your install and read consent state with the JavaScript API.
  </Card>

  <Card title="JavaScript API" href="/api">
    The full `window.OptinStack` surface: choices, events, and UI helpers.
  </Card>

  <Card title="Integrations" href="/integrations">
    Platform-specific setup for Webflow, Framer, Next.js, and more.
  </Card>

  <Card title="Domain scans" href="/domain-scans">
    Understand production and development hostnames, reverse proxies, and scan limits.
  </Card>
</Cards>
