---
title: "@c15t/browser client options"
description: Shared option tables for the @c15t/browser client, used by the HTML
  and JavaScript guides.
group: reference
lastModified: "2026-10-10T14:59:21+01:00"
lastAuthor: Kaylee
---
## Connection and policy

The `init()` and `createConsentClient()` of the `@c15t/browser` ES module,
`@c15t/browser/headless` and `@c15t/browser/iab` take `mode` as a factory
and none of the connection options below it. The script-tag builds and the
`@c15t/browser/hosted` and `@c15t/browser/offline` entries take the rest of
the table: `c15t.js` and `@c15t/browser/hosted` accept hosted mode only and
require a backend URL or hosted factory, and `c15t.offline.js` and
`@c15t/browser/offline` accept offline mode only.

|Option|Type|Default|What it does|
|--|--|--|--|
|`mode`|A transport factory. Script-tag builds also take `'hosted'`, `'offline'` or `'manifest'`.|Required in the ES modules. Script-tag builds pick it from the other options.|A factory from `manifest()`, `hosted()`, `offline()` or `custom()` is used as is; see [consent modes](/docs/concepts/modes). In the script-tag builds, `manifest` when `manifest` or `manifestURL` is set, `hosted` when `backendURL` is set, otherwise `offline`. Hosted mode without `backendURL` throws.|
|`backendURL`|`string`|none|Script-tag builds, `/hosted` and `/offline` entries. Your Inth or self-hosted backend URL, for hosted and manifest modes. In the ES modules, pass it to the factory, such as `hosted({ backendURL })`.|
|`manifest`|`ConsentManifest`|none|Script-tag builds. The backend's policy manifest, inlined in the page, for manifest mode. In the ES modules, `manifest({ snapshot })`.|
|`manifestURL`|`string`|none|Script-tag builds. Where manifest mode fetches the manifest. A URL that ends in `/manifest` also gives the backend URL; any other URL needs `backendURL` too. In the ES modules, `manifest({ manifestURL })`.|
|`policyRules`|array of policy rules or preset names|recommended rules|Script-tag builds and the `/hosted` and `/offline` entries. Offline mode only. A preset name such as `'europeOptIn'` stands for that preset in `policyRulePresets`. An unknown name throws. In the ES modules, `offline({ policyRules })` with rule objects.|
|`overrides`|`{ country?, region?, language?, gpc? }`|none|The visitor's location, language or GPC signal, when the page knows it. Policy matching uses these instead of detection.|
|`prefetch`|kernel configuration|none|A server-resolved init answer. When it carries a resolved policy, the client renders from it and does not call `/init`.|
|`enabled`|`boolean`|`true`|`false` grants every category, shows no UI and loads every configured script at once.|

## Scripts, blockers and data

|Option|Type|Default|What it does|
|--|--|--|--|
|`scripts`|`Script[]`|`[]`|Vendor scripts to load once their category is allowed. Each entry needs `id`, `category`, and `src` or `textContent`.|
|`consentCategories`|category names|categories your scripts, iframes and rules use|The categories the preference dialog offers, within the policy's scope. `necessary` is always included.|
|`networkBlocker`|`{ rules, enabled?, logBlockedRequests?, onRequestBlocked? }` or `false`|off|Hold `fetch` and `XMLHttpRequest` calls that match a rule until the rule's category is allowed.|
|`iframeBlocker`|`{ disableAutomaticBlocking? }` or `false`|on|Gate iframes that carry `data-category` or `data-vendor`. `false` turns it off. With `disableAutomaticBlocking: true`, c15t checks iframes only when you call `processIframes()`.|
|`nonce`|`string`|none|Content Security Policy nonce for the stock UI's `<style>` element and every `<script>` the `scripts` option loads. A script's own `nonce` wins. With a nonce set, c15t runs only the `<script type="text/plain" data-c15t-category>` tags that carry the same `nonce`.|
|`scriptLoader`|`{ onDebug? }`|none|`onDebug` receives every script loader lifecycle event.|
|`vendors`|`Vendor[]`|none|Vendors offered for vendor-level consent outside IAB. The preference dialog lists a switch for each. They merge with vendors from the backend, `vendor` fields on scripts and rules, and `data-c15t-vendor` on gated tags.|
|`clearOnRevocation`|cookies and storage keys per category|off|Delete named cookies and storage keys when their category is denied. Read once, at start.|
|`reloadOnConsentRevoked`|`boolean`|`true`|Reload the page after an accept, reject or save turns off a category that was allowed, once the save request finishes.|
|`callbacks`|`{ onChoiceRecorded?, onPermissionsChanged?, onError?, onBeforeConsentRevocationReload? }`|none|Functions c15t calls on consent events.|
|`storageConfig`|`{ storageKey?, crossSubdomain?, defaultDomain?, defaultExpiryDays? }`|key `c15t`, current host, 365 days|The name, domain and lifetime of the consent cookie and localStorage key.|
|`persistence`|`boolean` or `{ storageConfig?, skipHydration?, sync? }`|`true`|Read and write choices in the cookie and localStorage, and follow other tabs. `false` keeps choices in memory only. `{ sync: false }` stops following other tabs.|
|`user`|`{ externalId, identityProvider?, identityToken?, externalIdType?, properties? }`|none|An identified visitor, sent with consent records. [`identityToken`](/docs/self-host/api/node-sdk#verify-a-link-made-in-the-browser) verifies the link. Links only a subject the next save creates; use `identify()` for an existing one.|
|`iab`|IAB options or `false`|none|CMP settings such as `cmpId` and `vendors`. Only the IAB build accepts it; the other builds throw when it is set.|

## Presentation and copy

|Option|Type|Default|What it does|
|--|--|--|--|
|`ui`|UI options or `false`|stock UI on|Theme tokens, CSS, surfaces and mounting. `false` starts the client with no UI. See [UI options](#ui-options).|
|`presentation`|`{ prompt?, preferences? }`|floating banner, bottom left|Banner shape, position, button layout and blocking, within what the policy allows.|
|`i18n`|`{ locale?, messages }`|English|The language to start in, and messages per language that override the bundled, backend or manifest copy key by key for that language.|
|`legalLinks`|`{ privacyPolicy?, cookiePolicy?, termsOfService? }`|none|Each link is `{ href, label?, target?, rel? }`. The banner and dialog show only the links their `legalLinks` option lists.|

## UI options

These go under `ui`. The headless builds ignore them.

|Option|Type|Default|What it does|
|--|--|--|--|
|`theme`|theme tokens|none|Colors, radius, typography, spacing and motion. The same token object every c15t package takes.|
|`css`|`string`|none|CSS added after the bundled stylesheet, in the same root as the UI.|
|`colorScheme`|`'light'`, `'dark'` or `'system'`|`'system'`|Which token set to use. `system` follows the visitor's setting and updates when it changes.|
|`shadow`|`boolean`|`true`|Render inside a shadow root. `false` renders into the page, where your stylesheet applies.|
|`styles`|`boolean`|`true`|Include the bundled stylesheet. Set `false` with `shadow: false` when the page loads the stylesheet itself.|
|`noStyle`|`boolean`|`false`|Render markup with no c15t classes and no bundled stylesheet, for fully custom CSS. `theme` and `css` still apply.|
|`disableAnimation`|`boolean`|the visitor's reduced motion setting|Show and hide surfaces without transitions.|
|`container`|element or CSS selector|`document.body`|Where the UI host element is appended. A selector that matches nothing throws.|
|`banner`|`boolean` or banner options|`true`|`false` renders no banner. An object sets copy and behavior; see the banner options.|
|`dialog`|`boolean` or dialog options|`true`|`false` renders no preference dialog.|
|`trigger`|`boolean` or trigger options|`false`|Render the floating button that reopens the dialog.|
|`iab`|`{ loadErrorText?, saveErrorText?, moreVendorsText? }`|translated copy|Copy for the IAB vendor list states. IAB build only.|

## Banner options

These go under `ui.banner`.

|Option|Type|Default|What it does|
|--|--|--|--|
|`title`|`string`|translated title|Heading. A notice uses the notice title by default.|
|`description`|`string`|translated description|Body text. A notice uses the notice description by default.|
|`acceptButtonText`|`string`|"Accept All"|Label of the accept button.|
|`rejectButtonText`|`string`|"Reject All"|Label of the reject button.|
|`customizeButtonText`|`string`|"Customize"|Label of the button that opens the dialog.|
|`legalLinks`|list of `privacyPolicy`, `cookiePolicy`, `termsOfService`, or `null`|none|Which configured legal links to show after the description. `null` or `[]` shows none.|
|`hideBranding`|`boolean`|`false`|Hide the "Secured by" tag. The IAB banner always keeps it.|
|`scrollLock`|`boolean`|from `presentation`|Deprecated. Use `presentation.prompt.blocking`.|
|`trapFocus`|`boolean`|from `presentation`|Deprecated. Use `presentation.prompt.blocking`.|

The dismiss button of a notice always uses the translated
`common.acknowledge` label. Change it through `i18n`.

## Dialog options

These go under `ui.dialog`.

|Option|Type|Default|What it does|
|--|--|--|--|
|`legalLinks`|list of `privacyPolicy`, `cookiePolicy`, `termsOfService`, or `null`|none|Which configured legal links to show after the description.|
|`hideBranding`|`boolean`|`false`|Hide the "Secured by" tag at the bottom of the dialog.|

The dialog's title, description, category names and button labels come
from translations. Change them through `i18n`.

## Trigger options

`ui.trigger: true` shows the trigger with its defaults. An object sets these:

|Option|Type|Default|What it does|
|--|--|--|--|
|`position`|`'bottom-right'`, `'bottom-left'`, `'top-right'` or `'top-left'`|`'bottom-right'`|The corner the button starts in.|
|`size`|`'sm'`, `'md'` or `'lg'`|`'md'`|Button size.|
|`showWhen`|`'always'` or `'after-consent'`|`'always'`|`after-consent` hides the button until the visitor has answered the prompt.|
|`ariaLabel`|`string`|"Open privacy settings"|The button's accessible name. It has no visible text.|
|`persistPosition`|`boolean`|`true`|Remember the corner a visitor dragged the button to, in localStorage. A remembered corner wins over `position`.|

|Value|What a click does|
|--|--|
|`accept`|Like the banner's accept button, allows every category the dialog offers without IAB. Under an IAB policy it confirms the vendors' declared processing through the CMP. Optional categories without declared consent purposes remain denied. See [categories under an IAB policy](/docs/concepts/consent-state#categories-under-an-iab-policy).|
|`reject`|Rejects every optional category the dialog offers.|
|`customize`|Opens the preference dialog. Records nothing.|
|`dismiss`|Dismisses a notice. This records an acknowledgement, not consent, and does nothing unless the policy shows a notice.|
|`banner`|Shows the banner again. Records nothing.|
|`close`|Closes the banner or dialog. Records nothing.|

|Event|Payload|When it fires|
|--|--|--|
|`ready`|the snapshot|The policy has resolved and the UI can render. For a returning visitor, `hasConsented()` is reliable from here.|
|`consent`|the snapshot|Permissions, the recorded choice or the vendor switches changed. This includes a stored choice restored at start, a save, an expiry and a GPC change.|
|`ui`|`'banner'`, `'dialog'` or `'none'`|The surface c15t wants shown changed.|
|`error`|the error|A backend call failed, or an IAB step failed.|

A `ready` listener added after the policy resolved runs at once with the
snapshot from that moment. A `ui` listener added after that runs at once
with the current surface. `consent` and `error` listeners only hear later
changes.
