Files

5.6 KiB

consent

Banner zgody na cookies (GDPR): 4 kategorie (necessary / functional / analytics / marketing), zapis w cookie z wersjonowaniem, Google Consent Mode, treść z globala CookieSettings. Domyślny wygląd w czystym Tailwind, nadpisywalny.

Zależność

Banner używa ikony z lucide-react:

"dependencies": { "lucide-react": "^0.400.0" }

Config

Brak opcji — global CookieSettings jest zawsze budowany. Edytor zarządza treścią bannera (message, przyciski, kategorie, settingsTitle) w panelu, localized. Link do polityki prywatności bierze się z system pages (privacyPolicy), nie z osobnego pola.

Front — Provider + banner

Provider owija aplikację, banner i button renderują się same. Import z @intecion/ipal-kit/client:

// app/(frontend)/[locale]/layout.tsx
import { ConsentProvider, CookieBanner, CookieButton } from '@intecion/ipal-kit/client'
import { getConsentTexts } from '@intecion/ipal-kit'

export default async function Layout({ children, params }) {
  const { locale } = await params
  const payload = await getPayload({ config })

  // teksty z CookieSettings + link do polityki z system pages
  const settings = await payload.findGlobal({ slug: 'site-settings', locale: 'all', depth: 1 })
  const texts = await getConsentTexts({
    payload, config: i18nConfig, locale,
    privacyPolicy: { label: 'Polityka prywatności', page: settings.privacyPolicy },
  })

  return (
    <ConsentProvider texts={texts}>
      {children}
      <CookieBanner />
      <CookieButton />
    </ConsentProvider>
  )
}

Nadpisywanie wyglądu (Poziom 2)

Domyślne klasy Tailwind można nadpisać przez classNames:

<CookieBanner classNames={{
  root: 'fixed inset-x-0 bottom-0 ...',   // Twój layout
  primaryButton: 'btn btn-primary',        // np. DaisyUI
  secondaryButton: 'btn btn-ghost',
}} />

Gating skryptów wg zgody

import { updateConsent, setDefaultConsent } from '@intecion/ipal-kit'
// wysyła sygnały do Google Consent Mode (gtag) na podstawie stanu zgody

Logika (kategorie, storage, parsowanie) też jest dostępna server-safe z @intecion/ipal-kit:

import { parseConsent, CONSENT_COOKIE, CONSENT_CATEGORIES } from '@intecion/ipal-kit'
// np. gating skryptów server-side na podstawie cookie zgody

Wygląd — nadpisywanie stylów

Banner i przycisk mają domyślny, neutralny wygląd (light + dark) i działają bez żadnej konfiguracji. Kolory i zaokrąglenia idą przez CSS custom properties z fallbackami — żeby przestylować pod klienta, zadeklaruj zmienne w swoim CSS. Bez importów, bez propsów, bez walki ze specificity:

/* global.css — wszystko opcjonalne, nadpisz tylko to, co chcesz */
:root {
  --ipal-primary: #16a34a;
  --ipal-primary-hover: #15803d;
  --ipal-radius: 1rem;
}

Dostępne tokeny (każdy ma odpowiednik -dark używany pod dark:):

Token Domyślnie Co koloruje
--ipal-surface #fff tło bannera i przycisku
--ipal-border #e5e5e5 obramowania
--ipal-text #404040 tekst treści
--ipal-text-strong #171717 nagłówki, nazwy kategorii
--ipal-text-muted #737373 opisy kategorii
--ipal-primary #2563eb przycisk główny, ikona, link, checkbox
--ipal-primary-hover #1d4ed8 hover przycisku głównego
--ipal-primary-text #fff tekst na przycisku głównym
--ipal-hover #f5f5f5 hover przycisków drugorzędnych
--ipal-radius 0.375rem zaokrąglenie przycisków

Wymaga @source skanującego pakiet (patrz getting-started.md) — inaczej Tailwind nie wygeneruje tych klas.

Gdy tokeny nie wystarczą

Układ (odstępy, pozycja, breakpointy) nie jest tokenizowany — to nie jest coś, co zmienia się per brand, a wystawienie go oznaczałoby wymyślanie CSS od nowa, zmienna po zmiennej. Na większe zmiany są classNames:

<CookieBanner classNames={{
  root: 'fixed inset-0 z-50 grid place-items-center bg-black/50',  // modal zamiast paska
  primaryButton: 'btn btn-primary',                                 // np. DaisyUI
  secondaryButton: 'btn btn-ghost',
}} />
<CookieButton className="fixed bottom-6 right-6 ..." />

Sloty: root, primaryButton, secondaryButton. Podany className zastępuje domyślny (nie dokleja się).

Elementy mają też data-ipal="banner" i data-ipal="cookie-button" — stabilne uchwyty do CSS albo testów e2e.

Plugin sam zarządza jedną cookie functional: NEXT_LOCALE (wybór języka). Nie musisz nic konfigurować — działa out of the box:

  • Zapis za zgodą. Middleware zapisuje NEXT_LOCALE tylko, gdy użytkownik zaakceptował kategorię functional. Bez zgody język działa (negocjacja per żądanie), ale nie jest utrwalany w cookie.
  • Sprzątanie po cofnięciu. Gdy użytkownik cofnie zgodę na functional, hook consent usuwa NEXT_LOCALE automatycznie. Odpowiada za to DEFAULT_COOKIE_MAP:
const DEFAULT_COOKIE_MAP = {
  functional: [LOCALE_COOKIE_NAME],   // 'NEXT_LOCALE' — plugin zna własną cookie
}

Jeśli ustawiasz własne cookie podlegające zgodzie, rozszerz mapę — hook wtedy sprzątnie też Twoje po cofnięciu zgody:

useConsent({
  functional: ['NEXT_LOCALE', 'moje-ustawienie'],
  analytics: ['_ga', '_gid'],
})

Przekazana mapa zastępuje domyślną — pamiętaj dołączyć NEXT_LOCALE, jeśli chcesz zachować sprzątanie locale (albo zaimportuj LOCALE_COOKIE_NAME i dodaj).

Mechanizm zgody dla locale jest opisany też od strony i18n: i18n.md.