Zero-config Presets

Get a fully compliant NDPA 2023 implementation running in three files with presets

What Are Presets?

Presets are pre-assembled configurations that wire together the most common compliance scenarios with sensible defaults. Instead of manually choosing categories, writing copy, picking an adapter, and configuring callbacks, you import a preset and it handles all of that for you.

Every preset is fully overridable — treat it as a starting point, not a constraint. You can pass any prop supported by the underlying compound components to override individual defaults.

When to Use Presets vs. Compound Components

  • Presets — you want a working implementation today with minimal code
  • Compound components — you need a bespoke layout or highly custom UI
  • You can mix them: start with a preset, then swap individual sub-components as needed

3-File Quickstart

The fastest way to achieve NDPA 2023 compliance is to add three files to your Next.js project. The example below uses the ndprPreset for a minimal setup — consent banner, a privacy policy page, and a data subject request (DSR) form.

File 1: Root layout — add NDPRProvider

// src/app/layout.tsx
import { NDPRProvider, ndprPreset } from '@tantainnovative/ndpr-toolkit';
import '@tantainnovative/ndpr-toolkit/styles';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <NDPRProvider preset={ndprPreset}>
          {children}
        </NDPRProvider>
      </body>
    </html>
  );
}

File 2: Privacy policy page

// src/app/privacy-policy/page.tsx
import { PrivacyPolicyPreset } from '@tantainnovative/ndpr-toolkit';

export default function PrivacyPolicyPage() {
  return (
    <main className="max-w-3xl mx-auto py-12 px-4">
      <PrivacyPolicyPreset
        organization="Acme Ltd"
        email="privacy@acme.ng"
        website="https://acme.ng"
      />
    </main>
  );
}

File 3: DSR (data subject request) page

// src/app/data-rights/page.tsx
import { DSRPreset } from '@tantainnovative/ndpr-toolkit';

export default function DataRightsPage() {
  return (
    <main className="max-w-2xl mx-auto py-12 px-4">
      <DSRPreset
        organizationName="Acme Ltd"
        onSubmit={async (submission) => {
          await fetch('/api/dsr', {
            method: 'POST',
            body: JSON.stringify(submission),
          });
        }}
      />
    </main>
  );
}

That is a fully functional, NDPA 2023-compliant implementation. The consent banner, privacy policy, and DSR form are live with no additional configuration.

All 8 Presets

PresetDefault BehaviourRequired Props
ndprPresetConsent banner (bottom), localStorage adapter, 3 default categories
ConsentPresetStandalone consent banner, cookie-based storage, NDPA-compliant category labels
DSRPresetFull DSR form with all 6 NDPA request types, success confirmation, email notification hookorganizationName, onSubmit
DPIAPresetMulti-section DPIA questionnaire with risk matrix, PDF exportprojectName
BreachPresetBreach notification form, 72-hour timer, NDPC reporting checklistonSubmit
PrivacyPolicyPresetFull NDPA-compliant privacy policy with all required clauses, auto-dateorganization, email
LawfulBasisPresetActivity tracker with all 6 NDPA lawful bases, expiry alerts, audit log
ROPAPresetRecord of Processing Activities register, CSV/PDF export, Article 44 referencesorganizationName

Overriding Preset Defaults

Preset components accept the same props as the underlying compound components. Any prop you supply takes precedence over the preset default. Here are common overrides:

Custom categories

import { ConsentPreset } from '@tantainnovative/ndpr-toolkit';

const myCategories = [
  { id: 'necessary', label: 'Essential', description: '...', required: true },
  { id: 'performance', label: 'Performance', description: '...' },
  { id: 'social', label: 'Social Media', description: '...' },
];

// Overrides the preset's default categories
<ConsentPreset categories={myCategories} />

Custom position and styling

<ConsentPreset
  position="top"           // 'top' | 'bottom' | 'center'
  theme="dark"             // 'light' | 'dark' | 'system'
  classNames={{
    banner: 'border-t-2 border-green-500',
    acceptButton: 'bg-green-600 hover:bg-green-700',
  }}
/>

Custom copy

<ConsentPreset
  title="Your privacy, your choice"
  description="We collect data only with your permission and in line with the NDPA 2023."
  acceptAllLabel="Yes, I agree"
  rejectAllLabel="No thanks"
  privacyPolicyUrl="/legal/privacy"
/>

Using Presets with NDPRProvider

NDPRProvider is an optional root provider that forwards a preset — and optionally an adapter — to all toolkit components in your React tree. This is the recommended approach for Next.js app router projects because it avoids prop-drilling the preset configuration.

// src/app/layout.tsx
import {
  NDPRProvider,
  ndprPreset,
  apiAdapter,
} from '@tantainnovative/ndpr-toolkit';

const consentAdapter = apiAdapter({ baseUrl: '/api/consent' });

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <NDPRProvider
          preset={{
            ...ndprPreset,
            // Override specific preset fields at the provider level
            consentPosition: 'bottom',
            privacyPolicyUrl: '/privacy',
          }}
          adapter={consentAdapter}
        >
          {children}
        </NDPRProvider>
      </body>
    </html>
  );
}

Using Presets with Custom Adapters

All presets default to localStorageAdapter. Pass a different adapter via the adapter prop (or via NDPRProvider) to switch to API-backed storage:

import {
  ConsentPreset,
  composeAdapters,
  localStorageAdapter,
  apiAdapter,
} from '@tantainnovative/ndpr-toolkit';

const adapter = composeAdapters([
  localStorageAdapter,
  apiAdapter({ baseUrl: '/api/consent' }),
]);

export function App() {
  return <ConsentPreset adapter={adapter} />;
}

See the Storage Adapters guide for the full adapter API and the composeAdapters pattern.