# 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`: ```json "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`: ```tsx // 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 ( {children} ) } ``` ## Nadpisywanie wyglądu (Poziom 2) Domyślne klasy Tailwind można nadpisać przez `classNames`: ```tsx ``` ## Gating skryptów wg zgody ```ts 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`: ```ts 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: ```css /* 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`: ```tsx ``` 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. ## Locale jako cookie functional (wbudowane) 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`: ```ts const DEFAULT_COOKIE_MAP = { functional: [LOCALE_COOKIE_NAME], // 'NEXT_LOCALE' — plugin zna własną cookie } ``` ### Twoje własne cookie functional/analytics Jeśli ustawiasz własne cookie podlegające zgodzie, rozszerz mapę — hook wtedy sprzątnie też Twoje po cofnięciu zgody: ```ts 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](./i18n.md#cookie-locale-a-zgoda-rodo).