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

Every hook reads the runtime from the `ConsentRoot` set up in your
[App Router](/docs/frameworks/next/app-router) or
[Pages Router](/docs/frameworks/next/pages-router) guide, so call them from a
Client Component rendered inside that root and import them from
`c15t/next`.

```tsx title="components/optional-feature.tsx"
'use client';

import { useConsent } from 'c15t/next';

export function 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

Place this Client Component inside your existing consent boundary.

```tsx title="components/reject-button.tsx"
'use client';

import { useSaveConsents } from 'c15t/next';

export function 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.
