Consenti
Tutorial — Frontend Only — Step 3 of 6

Custom Profile

Define your own cookies, categories, and text with ConsentiProfile.

For full control over cookies, categories, and copy — not just overrides — define a ConsentiProfile in code:

ts
import { ConsentiProfile, ConsentiSetup } from '@consenti/ui'

const profile = new ConsentiProfile({
  defaultLocale: 'en',
  expiryDays: 365,
  cookies: {
    necessary: {},
    analytics: { listenGpc: true },
    marketing: { listenGpc: true },
  },
  translations: {
    en: {
      mainBanner: {
        position: 'bottom',
        heading: 'We value your privacy',
        htmlText: 'We use cookies to improve your experience.',
        buttons: {
          'accept-all': { text: 'Accept All', style: 'primary', action: 'custom', cookies: '*' },
          'reject-optional': { text: 'Reject Optional', style: 'secondary', action: 'custom', cookies: '!' },
          'customize': { text: 'Customize', style: 'secondary', action: 'manage' },
        },
      },
      preferenceModal: {
        heading: 'Cookie Preferences',
        subheading: 'Choose which cookies you allow.',
        position: 'center',
        showClose: true,
        overlayOpacity: 50,
        buttons: {
          'accept-all': { text: 'Accept All', style: 'primary', action: 'custom', cookies: '*' },
          'save-preferences': { text: 'Save Preferences', style: 'primary', action: 'submit' },
          'reject-optional': { text: 'Reject Optional', style: 'text', action: 'custom', cookies: '!' },
        },
        categories: {
          necessary: { heading: 'Strictly Necessary', htmlText: 'Required for the site to function.', legalBasis: 'mandatory', cookies: ['necessary'] },
          analytics: { heading: 'Analytics', htmlText: 'Helps us understand how visitors use the site.', legalBasis: 'consent', cookies: ['analytics'] },
          marketing: { heading: 'Marketing', htmlText: 'Used to personalise ads and measure campaigns.', legalBasis: 'consent', cookies: ['marketing'] },
        },
      },
    },
  },
})

new ConsentiSetup({
  compliance: { type: profile.getType() },
  // The registered ConsentiProfile takes precedence over the pre-built one
})
💡This step is optional — skip it if profileOverride already covers what you need. See Advanced Profile for multi-locale profiles and the full resolution order.

Optional profile-level configs

Pick whichever of these your compliance requirements call for — none are required.

gpcBanner — a dedicated banner when GPC is detected

Add a gpcBanner key alongside mainBanner in a locale. Falls back to mainBanner if omitted.

ts
translations: {
  en: {
    mainBanner: { /* ... */ },
    gpcBanner: {
      position: 'bottom',
      heading: 'Privacy signal detected',
      htmlText: "Your browser's GPC signal was detected. Ad cookies have been pre-denied.",
      showClose: false,
      buttons: {
        'understood': { text: 'Understood', style: 'primary', action: 'custom', cookies: '!' },
        'customize': { text: 'Customize', style: 'secondary', action: 'manage' },
      },
    },
    preferenceModal: { /* ... */ },
  },
}

gpcMode — how strictly GPC is honored

ts
new ConsentiProfile({
  gpcMode: 'strict', // 'ignore' | 'honor' | 'strict'
  // ...
})

Overridden at runtime by core.autoHonorGPC on ConsentiSetupwhen that's explicitly set.

Other optional profile fields

ts
new ConsentiProfile({
  allowReceipt: true,    // shows "Download consent receipt" in the modal footer
  hidePoweredBy: true,   // suppresses the "Powered by Consenti" footer link (default: hidden)
  darkMode: true,        // default dark-mode state for this profile
  // ...
})