---
title: Hooks
description: Gate features and save consent choices in React components with the
  focused hooks exported from c15t/react.
group: frameworks
lastModified: "2026-10-10T16:01:45+01:00"
---
## Read only the state you need

Every hook reads the runtime from the nearest `ConsentProvider`, so call them
from components rendered inside that provider and import them from
`c15t/react`.

```tsx title="src/optional-feature.tsx"
import { useConsent } from 'c15t/react';

export const OptionalFeature = () => {
	const allowed = useConsent('marketing');
	return allowed ? <div>Optional marketing content</div> : null;
};
```

Call hooks inside the consent provider. `useConsent` reads effective permission,
which can be true under an opt-out policy without a recorded grant.

|Need|Hook|
|--|--|
|One category's current permission|`useConsent(category)`|
|All current permissions|`useConsents()`|
|Recorded per-category choices|`useExplicitChoice()`|
|Whether one declared vendor may run|`useVendorAllowed(id)`|
|Whether a prompt is required|`usePromptRequirement()`|
|Active policy and resolution|`usePolicyRule()`, `usePolicyResolution()`|
|Save an explicit choice|`useSaveConsents()`|
|Open or close a consent surface|`useSetActiveUI()`|
|Acknowledge a notice|`useDismissNotice()`|

## Save from a visitor action

Render this component inside your existing `ConsentProvider`.

```tsx title="src/reject-button.tsx"
import { useSaveConsents } from 'c15t/react';

export const RejectButton = () => {
	const save = useSaveConsents();
	return (
		<button
			type="button"
			onClick={() => {
				void save('none');
			}}
		>
			Reject optional
		</button>
	);
};
```

This is an isolated action example, not a complete policy-aware banner. Use the
stock UI or headless surface actions for a complete prompt. Do not call save on
mount to persist a state derived from permissions.

Use focused hooks for feature gates. For a complete custom prompt or preference
center, use `useHeadlessConsentUI()` for surface actions and `useConsentDraft()`
for staged choices, inside one `ConsentDraftProvider` so the save commits the
same draft. v3 has no `useConsentManager()`; the
[`use-consent-manager-to-hooks` codemod](/docs/cli/commands/codemods#migrate-useconsentmanager-to-v3-hooks)
rewrites most of its calls to hooks. Read [how consent works](/docs/concepts/how-consent-works#a-permission-is-not-a-recorded-choice) before
treating a callback as evidence of a choice.
