Skip to main content

React Components

ConsentProvider

Mount one provider

ConsentProvider creates the consent runtime, loads the policy, stores the visitor's choice and loads consent-gated scripts. Render one provider at the root of your app and put the banner, dialog and a preferences link inside it. The quickstart does this in src/consent.tsx:

src/consent.tsx
import { posthog } from '@c15t/integrations/posthog';
import {
	ConsentBanner,
	ConsentDialog,
	ConsentDialogLink,
	ConsentProvider,
	manifest,
} from 'c15t/react';
import type { ReactNode } from 'react';

const options = {
	// The policy the build downloaded from VITE_C15T_BACKEND_URL.
	mode: manifest(),
	scripts: [
		posthog({
			id: 'phc_your_project_key',
			initOptions: { cookieless_mode: 'never' },
			loadMode: 'after-consent',
		}),
	],
};

export const Consent = ({ children }: { children: ReactNode }) => (
	<ConsentProvider options={options}>
		{children}
		<ConsentBanner />
		<ConsentDialog />
		<footer>
			<ConsentDialogLink>Privacy settings</ConsentDialogLink>
		</footer>
	</ConsentProvider>
);

manifest() from c15t/react resolves the policy from the snapshot consentManifest() bundled, and sends consent choices to the backend URL the plugin read from VITE_C15T_BACKEND_URL or VITE_INTH_PROJECT_URL. Set one to the backend URL from your Inth project. To fetch the policy from the backend on every page load instead, pass hosted() from c15t/react. The Next.js and TanStack Start adapters export ConsentRoot instead, which wraps this provider and passes it server-resolved state.

Provider options

Keep the provider mounted across client navigation. It reads mode, prefetch, persistence, storageConfig, clearOnRevocation, i18n and experiment once, when it mounts. Outside production, changing mode, i18n, experiment, persistence or storageConfig logs a warning. Remount the provider to change them. scripts, vendors, networkBlocker, iframeBlocker, consentCategories, overrides, user, callbacks and enabled apply when they change.

OptionPurpose
modeRequired. manifest() for a bundled policy, hosted() for the backend's /init, offline() for local policies, all from c15t/react, or custom() for your own transport. See consent modes
prefetchServer-resolved state, or a promise of it, from a framework adapter's server helper
scriptsConsent-gated vendor scripts. See scripts and embeds
vendorsVendors listed under their category with their own switch. See vendor consent
scriptLoaderOptions for the script loader module
networkBlockerRules that hold fetch and XMLHttpRequest calls until their category is allowed, or false
iframeBlockerGates DOM iframes that carry data-category. On by default; false turns it off
persistenceStores the visitor's choice in a cookie and localStorage. On by default
storageConfigStorage key and cookie settings for the stored choice
clearOnRevocationCookies and storage keys to delete when a category is denied
reloadOnConsentRevokedReload the page after the visitor turns off a granted category or vendor. Defaults to true
consentCategoriesCategories the preference dialog offers alongside those your scripts use, within the policy's scope
overridesForce the country, region or language the policy is resolved for, for testing
userLink consent records to a signed-in user
callbacksChoice, permission and error events
i18nLanguages and message overrides
legalLinksPrivacy policy and other links shown in the banner and dialog
themeconsentActions and slot styles. Tokens go through ConsentTheme; see customize
componentsSlot attributes per component part
presentationBanner and dialog shape, position and blocking
experimentA/B test of presentation, read once at mount. See banner experiments
journeyRandom id that links each /init to the save that follows. See session reports
colorScheme'light', 'dark', 'system', or null to leave the c15t-dark class alone
noStyle, disableAnimationDrop the built-in styles, or turn off animations
preloadDialogWhen the deferred ConsentDialog starts loading: 'idle' (default) or 'intent'; see ConsentDialog
nonceContent Security Policy nonce for script elements c15t inserts
enabledSet false only when you deliberately bypass consent enforcement

enabled: false grants categories and allows gated loading while suppressing consent UI. It is not a way to fix failed initialization or hide a banner in production.

Observe changes without inventing choices

onChoiceRecorded reports explicit accept, reject and save actions. onPermissionsChanged also covers changes caused by policy, expiry or privacy signals. Hydration and notice dismissal do not become explicit choices.

An externally owned runtime can be passed through runtime. Its owner must start and dispose it. A provider borrowing that runtime must not initialize or dispose a second copy. Passing a different runtime moves the provider and its hooks to the new runtime's kernel and unsubscribes them from the previous one. The previous runtime keeps running until its owner disposes it. Switch the provider to another runtime, or unmount it, before disposing the runtime it renders. Changing between a borrowed runtime and a provider-created one still requires remounting the provider. IAB actions taken before its handle is ready wait for that handle. If the provider unmounts or switches runtimes first, a pending save() rejects with an AbortError instead of waiting indefinitely. See how consent works and choose your setup.

Reload after revocation

Removing a script cannot stop code that already ran. A vendor's listeners, timers and widgets keep working until the page unloads. When an accept, reject or save turns off a category or vendor that was granted, the provider reloads the page once the save request settles, so the next page runs only permitted code. onBeforeConsentRevocationReload runs just before the reload.

Otherwise, expiry, policy changes and privacy signals do not reload the page. Set reloadOnConsentRevoked: false only when every gated vendor stops itself on revocation, for example through its own opt-out API.

Set options.clearOnRevocation to declare cookies, localStorage keys, and sessionStorage keys by optional consent category. Cleanup waits for policy resolution, then clears denied categories and later allowed-to-denied transitions. This option is initial-only. See clear on revocation for examples, cookie scopes, and browser limits.