Compare commits

..
2 Commits
Author SHA1 Message Date
radoslaw.smolinski 5a322230ae 1.0.17 2026-08-24 19:06:11 +02:00
radoslaw.smolinski f919c288b2 i18n: rename locale cookie to NEXT_LOCALE (Next.js convention) 2026-08-24 19:06:06 +02:00
8 changed files with 96 additions and 8 deletions
+8 -1
View File
@@ -1,6 +1,13 @@
import type { I18nConfig } from './types.js';
/** Cookie name the template uses to persist a visitor's locale choice. */
export declare const LOCALE_COOKIE_NAME = "ipal-locale";
/**
* Cookie name for the persisted locale choice. Uses NEXT_LOCALE — the convention
* Next.js and its i18n ecosystem expect — so the cookie is interoperable with
* other libraries that read the active locale (instead of a plugin-specific
* name). Written only under functional consent; cleared when that consent is
* withdrawn (see consent cookieMap).
*/
export declare const LOCALE_COOKIE_NAME = "NEXT_LOCALE";
type NegotiateLocaleArgs = {
/** Raw Accept-Language header value */
acceptLanguage?: null | string;
+7 -1
View File
@@ -1,5 +1,11 @@
import { getLocaleCodes, isValidLocale } from './helpers.js';
/** Cookie name the template uses to persist a visitor's locale choice. */ export const LOCALE_COOKIE_NAME = 'ipal-locale';
/** Cookie name the template uses to persist a visitor's locale choice. */ /**
* Cookie name for the persisted locale choice. Uses NEXT_LOCALE — the convention
* Next.js and its i18n ecosystem expect — so the cookie is interoperable with
* other libraries that read the active locale (instead of a plugin-specific
* name). Written only under functional consent; cleared when that consent is
* withdrawn (see consent cookieMap).
*/ export const LOCALE_COOKIE_NAME = 'NEXT_LOCALE';
/**
* Resolves which locale to serve, in priority order:
* 1. Cookie (explicit prior choice)
File diff suppressed because one or more lines are too long
+1
View File
@@ -108,6 +108,7 @@ export default buildConfig({
| access | Role admin > editor > user, kontrola dostępu | [access.md](./access.md) |
| payload-helpers | getSiteSettings / getSiteIntegrations | [payload-helpers.md](./payload-helpers.md) |
| seo | Metadata, hreflang, auto-fill, plugin-seo | [seo.md](./seo.md) |
| architektura-tresci | **Jak budować, żeby klient wszystko edytował** (filozofia CMS) | [architektura-tresci.md](./architektura-tresci.md) |
| blocks | RenderBlocks — silnik renderowania bloków | [blocks.md](./blocks.md) |
| consent | Banner cookies GDPR, Google Consent Mode | [consent.md](./consent.md) |
| turnstile | Cloudflare Turnstile (widget + verify) | [turnstile.md](./turnstile.md) |
+36 -1
View File
@@ -109,7 +109,7 @@ Dostępne tokeny (każdy ma odpowiednik `-dark` używany pod `dark:`):
| `--ipal-hover` | `#f5f5f5` | hover przycisków drugorzędnych |
| `--ipal-radius` | `0.375rem` | zaokrąglenie przycisków |
Wymaga `@source` skanującego pakiet (patrz frontend-setup.md) — inaczej Tailwind
Wymaga `@source` skanującego pakiet (patrz getting-started.md) — inaczej Tailwind
nie wygeneruje tych klas.
### Gdy tokeny nie wystarczą
@@ -132,3 +132,38 @@ 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).
+32
View File
@@ -108,3 +108,35 @@ Zachowanie:
- wybrany locale zapisany w cookie (`LOCALE_COOKIE_NAME`)
`DEFAULT_MIDDLEWARE_MATCHER` wyklucza `api`, `admin`, `_next`, pliki statyczne.
## Cookie locale a zgoda (RODO)
Wybór języka zapisywany jest w cookie **`NEXT_LOCALE`** (konwencja Next.js —
kompatybilna z innymi bibliotekami i18n, które czytają aktywny locale). Ale
zapis podlega zgodzie: to cookie kategorii **functional**, więc:
- **Zapis TYLKO za zgodą.** Middleware zapisuje `NEXT_LOCALE` jedynie, gdy
użytkownik zgodził się na kategorię functional (`mayPersistLocale` sprawdza
zgodę). Bez zgody język działa per żądanie (negocjacja z Accept-Language),
ale nie jest utrwalany.
- **Sprzątanie po cofnięciu zgody.** Gdy użytkownik cofnie zgodę na functional,
cookie `NEXT_LOCALE` jest usuwane automatycznie (consent zna tę cookie przez
`DEFAULT_COOKIE_MAP` — patrz [consent.md](./consent.md)).
Nazwa cookie to jedna stała `LOCALE_COOKIE_NAME` (`modules/i18n/negotiateLocale`),
propagująca do middleware i sprzątania consent. Można nadpisać w
`createLocaleMiddleware({ cookieName })`, ale domyślnie `NEXT_LOCALE` jest
zalecane (interop).
### Kolejność negocjacji locale
1. Cookie `NEXT_LOCALE` (jeśli jest — czyli był wybór za zgodą)
2. Nagłówek `Accept-Language` (preferencje przeglądarki)
3. `defaultLocale` z konfiguracji
Wejście na `/` → negocjacja → redirect na `/pl` (albo wynik negocjacji).
Zmiana języka (URL `/en` różny od cookie) → zapis nowego wyboru (za zgodą).
> **Migracja ze starej nazwy:** wcześniej cookie nazywało się `ipal-locale`.
> Po zmianie na `NEXT_LOCALE` użytkownicy ze starą cookie przejdą raz ponowną
> negocjację (stara cookie ignorowana). Jednorazowe, bez wpływu na nowe projekty.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@intecion/ipal-kit",
"version": "1.0.16",
"version": "1.0.17",
"description": "Intecion Payload Advanced Library — a Payload CMS 3 plugin: i18n, SEO, forms, consent, analytics, blog/archives.",
"license": "MIT",
"repository": {
+8 -1
View File
@@ -3,7 +3,14 @@ import type { I18nConfig } from './types.js'
import { getLocaleCodes, isValidLocale } from './helpers.js'
/** Cookie name the template uses to persist a visitor's locale choice. */
export const LOCALE_COOKIE_NAME = 'ipal-locale'
/**
* Cookie name for the persisted locale choice. Uses NEXT_LOCALE — the convention
* Next.js and its i18n ecosystem expect — so the cookie is interoperable with
* other libraries that read the active locale (instead of a plugin-specific
* name). Written only under functional consent; cleared when that consent is
* withdrawn (see consent cookieMap).
*/
export const LOCALE_COOKIE_NAME = 'NEXT_LOCALE'
type NegotiateLocaleArgs = {
/** Raw Accept-Language header value */