first commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# cookieDetector
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`cookieDetector` is a `LocaleDetector` that reads/writes the active
|
||||
locale via a single cookie. It runs in both server and browser
|
||||
environments, making it the natural persistence story for stateless
|
||||
visitors who have not yet authenticated. On the server it consumes the
|
||||
inbound `Cookie` header and writes a `Set-Cookie` header onto
|
||||
`ctx.responseHeaders`; on the browser it goes through `document.cookie`.
|
||||
The detector URL-encodes values on persist and decodes them on read so
|
||||
the wire format is robust against unusual locale identifiers.
|
||||
|
||||
## Features
|
||||
|
||||
- Configurable cookie name, max-age, SameSite, and path
|
||||
- Server read via `ctx.request.headers` and write via
|
||||
`ctx.responseHeaders`
|
||||
- Browser read/write via `document.cookie` (including `ctx.document`
|
||||
injection for tests)
|
||||
- URL-encoded values; safe parsing tolerates malformed segments and
|
||||
decode failures
|
||||
- `environment: "both"`
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { cookieDetector } from "@suaveplan/react-i18n/detector/cookie/cookie";
|
||||
import { createDetectorChain } from "@suaveplan/i18n/detector";
|
||||
|
||||
const chain = createDetectorChain([cookieDetector()]);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { cookieDetector } from "@suaveplan/react-i18n/detector/cookie/cookie";
|
||||
|
||||
// Cross-site embed scenario: SameSite=None requires Secure on real
|
||||
// browsers; the detector emits the SameSite attribute literally so the
|
||||
// host server can append `Secure` via its existing cookie middleware.
|
||||
const detector = cookieDetector({
|
||||
name: "app_locale",
|
||||
maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days
|
||||
sameSite: "none",
|
||||
path: "/embed",
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `cookieDetector(options?: CookieDetectorOptions): LocaleDetector`
|
||||
|
||||
Returns a `LocaleDetector` with `name: "cookie"` and
|
||||
`environment: "both"`. Both `detect` and `cache` are implemented.
|
||||
|
||||
### `CookieDetectorOptions`
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
| ------------- | ---------------------------------------- | -------------------- | ---------------------------- |
|
||||
| name | `string` | `"suaveplan_locale"` | Cookie name |
|
||||
| maxAgeSeconds | `number` | `31536000` | Cookie lifetime in seconds |
|
||||
| sameSite | `"lax" \| "strict" \| "none"` (default `"lax"`) | `"lax"` | SameSite attribute value |
|
||||
| path | `string` | `"/"` | Cookie path attribute |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The detector emits SameSite values capitalised (`Lax`, `Strict`,
|
||||
`None`) per the cookie spec; the input option stays lower-case so
|
||||
consumers don't have to remember the casing convention.
|
||||
- Cookie parsing tolerates segments without an `=` (skipped) and
|
||||
values that fail percent-decoding (returned raw rather than
|
||||
throwing).
|
||||
- The cookie writer uses `Headers.append('set-cookie', …)` so a single
|
||||
response may carry multiple Set-Cookie writes from sibling
|
||||
middleware.
|
||||
- An empty server cookie header transparently falls through to
|
||||
`document.cookie` so isomorphic test harnesses can stage a browser
|
||||
scenario inside a server-shaped `DetectorContext` by supplying only
|
||||
`globalThis.document`.
|
||||
Reference in New Issue
Block a user