---
title: "@c15t/browser options"
description: Every option init() and createConsentClient() from @c15t/browser
  accept in a bundled JavaScript app, from the mode to scripts, blockers,
  callbacks, storage, presentation and the stock UI.
group: frameworks
lastModified: "2026-10-10T16:01:45+01:00"
---
## Pass options to init

`init()` and `createConsentClient()` from `@c15t/browser`,
`@c15t/browser/headless` and `@c15t/browser/iab` take one options object:

```ts title="src/main.ts"
import { init, manifest } from '@c15t/browser';
import { posthog } from '@c15t/integrations/posthog';

init({
	mode: manifest(),
	scripts: [
		posthog({
			id: 'phc_your_project_key',
			initOptions: { cookieless_mode: 'never' },
			loadMode: 'after-consent',
		}),
	],
});
```

`mode` is required: a factory from `manifest()`, `hosted()`, `offline()` or
`custom()`, imported from the same entry. Every other option is optional. The
options are read when the client is created. To change
`ui`, call `mountUI()` again; to change anything else, dispose the client and
create a new one.

The mode-specific `@c15t/browser/hosted` and `@c15t/browser/offline` entries
accept the same UI, gating and lifecycle options. Their connection options
are restricted to their mode. The hosted entry requires a backend URL or a
hosted factory and rejects preset names; the offline entry rejects backend
and manifest options. See [mode-specific configuration](/docs/frameworks/javascript/api/browser#choose-a-bundle-for-one-mode).

## 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.|

[Transports](/docs/frameworks/javascript/transports) compares the modes and
shows each with an example.

## 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.|

Each has a guide: [scripts](/docs/frameworks/javascript/scripts),
[iframe blocker](/docs/frameworks/javascript/modules/iframe-blocker),
[network blocker](/docs/frameworks/javascript/modules/network-blocker),
[clear on revocation](/docs/frameworks/javascript/clear-on-revocation)
and [callbacks](/docs/frameworks/javascript/callbacks).

## 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`.|

[Customize](/docs/frameworks/javascript/customize) shows these options at
work.

## Options the client passes to the runtime

`@c15t/browser` builds a [consent runtime](/docs/frameworks/javascript/api/runtime)
for you and passes every option in the tables above through, including
`nonce`, `persistence`, `scriptLoader` and `vendors`. Two runtime options have
no client equivalent. The `@c15t/browser/iab` entry supplies `createIAB`, and
the client turns `windowDebug` off so the runtime does not replace
`window.c15t`.
