# Kibble installation contract: section 9 of 29 (guide version 3)

> This is **one section only**, not the whole contract. Complete document: https://www.usekibble.dev/AI/guide.md

## 9. The snippet and its options {#snippet}

Place this once in the document head of every page (a shared layout or template). The first script is a queue so calls made before the SDK loads are not lost.

HTML:

```html
<script>window.kibble=window.kibble||function(){(window.kibble.q=window.kibble.q||[]).push(arguments)};</script>
<script async src="https://use.example-kibble-host/sdk/v1/kibble.js"
  data-key="pk_YOUR_PROPERTY_KEY"
  data-endpoint="https://use.example-kibble-host"
  data-consent="manual"
  data-cookie-domain="example.com"
  data-connected-hosts="book.example.com"></script>
```

### Script attributes

| Attribute | Values | Default and effect |
| --- | --- | --- |
| `data-key` | the property key (`pk_...`) | **Required.** Without a key the SDK does nothing. |
| `data-endpoint` | collector origin, or the gateway base URL | Defaults to the origin of the script `src`. **Required** when the SDK is served through a first-party gateway path (for example `https://www.example.com/measure`), because only the origin of `src` is used, and when you use `window.kibbleConfig`. See [Cross-domain and first-party gateways](https://www.usekibble.dev/AI#gateways). |
| `data-consent` | `manual` or `google-consent-mode` | With it, the installation configures itself and never reads settings from Kibble; any other value is treated as `manual`. **Without it** (a key-only installation, 1.14.0) the consent source and the other settings come from Kibble by key, and if they cannot be fetched consent is `manual`. See [Consent](https://www.usekibble.dev/AI#consent) and [Google Tag Manager](https://www.usekibble.dev/AI#gtm). |
| `data-cookie-domain` | a registrable domain such as `example.com` | Writes a first-party `_kibble` cookie scoped to that domain, so subdomains share one browser identifier. Without it the identifier lives in `localStorage` only. |
| `data-connected-hosts` | comma-separated entries: `host` or `host/pattern` | Destinations for cross-domain continuity: other registered hosts of the same property. An entry `host/pattern` (for example `guest.rezstream.com/**/your-slug/**`) decorates only links whose path matches the pattern; a bare `host` decorates every link to it. Set it on both sides. See [Website hosts, external connections and first-party gateways](https://www.usekibble.dev/AI#gateways). |
| `data-tenant` | the provider tenant id, `[A-Za-z0-9._-]` up to 128 | Only for pages on an external connection's host. Sent as `tn` on every request; the collector refuses a tenant-scoped host without it. Implies `data-storage="property"`. See [Website hosts, external connections and first-party gateways](https://www.usekibble.dev/AI#gateways). |
| `data-routes` | comma-separated route patterns (up to 8) | Only for an external connection's host. The SDK does not start on a page outside them. See [Website hosts, external connections and first-party gateways](https://www.usekibble.dev/AI#gateways). |
| `data-storage` | `property` | Keeps the browser and stream ids under names scoped to the property key and writes no cookie. Use it on every host that is not a website host; `data-cookie-domain` is ignored with it. |
| `data-datalayer` | `1`, `true` or `on` | Off by default. Turns on the allowlisted dataLayer mapping. See [Google Tag Manager](https://www.usekibble.dev/AI#gtm). |
| `data-datalayer-gtag` | `1`, `true` or `on` | Off by default; only applies with `data-datalayer`. Also maps `gtag('event', name, params)` command entries. See [Google Tag Manager](https://www.usekibble.dev/AI#gtm). |
| `data-auto-candidates` | `false` to disable | On by default. `false` stops the automatic outcome candidates (thank-you-like URLs and ambiguous signals). |
| `data-flush-interval` | milliseconds | 5000. Clamped to 1000 to 60000. |
| `data-performance` | `off`, or a rate from `0.01` to `1` | On (rate 1) by default. `off` stops page performance measurement; a rate measures that share of page loads, decided once per page load. Counts are never scaled up. |
| `data-debug` | `true` | Off by default. With `true` the SDK writes short `console.debug` notices. |

- The SDK is small and has no runtime dependencies. A second copy on the same page is ignored with a console warning.
- Data tracking → Setup offers the key-only form (only `data-key`, plus `data-endpoint` behind a gateway: everything else is set in Kibble and fetched by key, exactly as for the [standard GTM tag](https://www.usekibble.dev/AI#gtm)). Its snippet with page settings sets `data-key`, `data-endpoint`, `data-consent`, and `data-cookie-domain` and `data-connected-hosts` when they apply. Each external connection has its own recipe on that page with `data-tenant`, `data-routes` and `data-storage` where they apply. Add other attributes yourself when needed.
- `data-cookie-domain` must be the real registrable domain shared by the website hosts (Kibble derives it from the Public Suffix List, so `example.co.uk` is right and `co.uk` never is). Check it before you ship it, and never set it on a connection host.
- The npm package `@kibble/sdk` is not published. Do not tell anyone to `npm install` it; use the script tag.

### window.kibbleConfig (when you cannot add attributes)

Some environments cannot put `data-*` attributes on the script tag (a sandboxed tag-manager template, for example). The SDK then reads `window.kibbleConfig`, set before the SDK script runs. It is used **only when there is no script tag with `data-key`**. `endpoint` is required here, because there is no script `src` to derive it from.

| Key | Type | Same as |
| --- | --- | --- |
| `key` | string | `data-key` |
| `endpoint` | string (required) | `data-endpoint` |
| `consent` | `"manual"` or `"google-consent-mode"` | `data-consent` |
| `cookieDomain` | string | `data-cookie-domain` |
| `connectedHosts` | a comma-separated **string**; arrays are ignored | `data-connected-hosts` |
| `tenant` | string | `data-tenant` |
| `routes` | a comma-separated string or an array | `data-routes` |
| `storage` | `"property"` | `data-storage` |
| `dataLayer` | `true` | `data-datalayer` |
| `dataLayerGtag` | `true` | `data-datalayer-gtag` |
| `autoCandidates` | `false` disables | `data-auto-candidates` |
| `flushInterval` | milliseconds | `data-flush-interval` |
| `performance` | `"off"` or a number from 0.01 to 1 | `data-performance` |
| `debug` | `true` | `data-debug` |

window.kibbleConfig:

```js
window.kibbleConfig = {
  key: 'pk_YOUR_PROPERTY_KEY',
  endpoint: 'https://use.example-kibble-host',
  consent: 'manual',
  connectedHosts: 'book.example.com'   // a comma string, not an array
};
window.kibble=window.kibble||function(){(window.kibble.q=window.kibble.q||[]).push(arguments)};
// then load https://use.example-kibble-host/sdk/v1/kibble.js without a data-key attribute
```

END OF SECTION snippet
