---
title: Troubleshooting
description: Solutions for common issues with @c15t/nextjs — provider errors, missing banners, consent persistence, and more.
---
## "Provider not found" Error

**Symptom:** `useConsentManager must be used within a ConsentManagerProvider` error.

**Fix:** Ensure the component calling `useConsentManager()` (or any c15t hook) is rendered inside a `ConsentManagerProvider`:

```tsx
// Wrong — hook is outside the provider
function App() {
  const { consents } = useConsentManager(); // throws
  return <ConsentManagerProvider options={...}>...</ConsentManagerProvider>;
}

// Correct — hook is inside the provider
function App() {
  return (
    <ConsentManagerProvider options={...}>
      <MyComponent /> {/* useConsentManager works here */}
    </ConsentManagerProvider>
  );
}
```

## Banner Doesn't Show

**Possible causes:**

1. **Opt-out jurisdiction** — In CCPA/opt-out regions, the banner is not shown because tracking is allowed by default. Check `model` from `useConsentManager()` — if it's `'opt-out'`, the banner is intentionally hidden.

2. **Consent already given** — If the user has already made a consent choice, the banner won't reappear. Clear cookies or use `resetConsents()` to test again.

3. **`activeUI` is `'none'`** — Something is explicitly setting `activeUI` to `'none'`. Check the DevTools panel for the current consent state.

4. **Backend not responding** — In `'c15t'` mode, the banner waits for the backend `/init` response. Check the Network tab for failed requests to your `backendURL`.

```tsx
// Debug: check what the consent manager sees
const { activeUI, model, isLoadingConsentInfo } = useConsentManager();
console.log({ activeUI, model, isLoadingConsentInfo });
```

## Consent Not Persisting

**Symptom:** Consent is lost after page reload.

**Possible causes:**

1. **Incognito/private mode** — Some browsers restrict cookie storage in private browsing.

2. **Cookie settings** — In `'offline'` mode, consent is stored in cookies. Ensure cookies are not being blocked by browser settings or extensions.

3. **Different domains** — Cookies are domain-scoped. If your dev server uses a different domain than production, consent won't carry over.

4. **Backend errors** — In `'c15t'` mode, check that the backend is saving consent successfully. Enable `debug: true` in provider options to see detailed logs.

## Scripts Not Loading

**Symptom:** Third-party scripts configured in the `scripts` option don't load after consent is granted.

**Checklist:**

1. **Wrong category name** — The `category` on the script must match one of the `consentCategories` names. For example, `'measurement'` not `'analytics'`.

2. **Consent condition not met** — Use `has('measurement')` to verify the category is actually consented.

3. **Script error** — Check the browser DevTools Console for script loading errors. The `onError` callback can help debug:

```tsx
{
  id: 'analytics',
  src: 'https://...',
  category: 'measurement',
  onError: ({ error }) => console.error('Script failed:', error),
}
```

4. **Ad blocker** — Browser extensions may block the script regardless of consent. The `anonymizeId` option (default: `true`) helps avoid pattern-based blocking.

## SSR Hydration Mismatch

**Symptom:** React hydration warnings, consent banner flashes briefly, or consent state differs between server and client.

**Fixes:**

1. **Missing `ssrData`** — Ensure you're passing the SSR data Promise to the provider. Do **not** `await` `fetchInitialData()` in Server Components:

```tsx title="app/layout.tsx"
import { fetchInitialData } from '@c15t/nextjs';
import ConsentManager from '@/components/consent-manager';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const ssrData = fetchInitialData({ backendURL: '/api/c15t' });

  return (
    <html lang="en">
      <body>
        <ConsentManager ssrData={ssrData}>
          {children}
        </ConsentManager>
      </body>
    </html>
  );
}
```

2. **Stale cache** — If using a CDN or caching layer, ensure the SSR data is fresh per-request and not shared across users.

3. **Debug with `useSSRStatus`** — Check if SSR data was actually consumed:

```tsx
const { ssrDataUsed, ssrSkippedReason } = useSSRStatus();
```

See [Server-Side Data Fetching](/docs/frameworks/next/server-side) for full SSR setup.

## TypeScript Errors

**Common import issues:**

```tsx
// Components and hooks — main entry point
import { ConsentManagerProvider, useConsentManager } from '@c15t/nextjs';

// Server-side data fetching
import { fetchInitialData } from '@c15t/nextjs';

// Headless (hooks only, no components)
import { useConsentManager } from '@c15t/nextjs/headless';
```

If you see type errors after updating, try:

```sh
rm -rf node_modules/.cache
bun install
```

## Still Stuck?

* Enable `debug: true` in provider options for verbose console logging
* Use the [DevTools](/docs/frameworks/next/components/dev-tools) panel to inspect live consent state
* Check the [GitHub issues](https://github.com/c15t/c15t/issues) for known bugs
