How ShipSafe handles cookies, and how to turn on a consent banner when you add non-essential analytics.
Default (essential only)
By default ShipSafe sets essential cookies only. config.cookies.nonEssentialEnabled is false, so no consent banner is shown on / or elsewhere.
| Cookie | Role |
|---|---|
session | Firebase session cookie (httpOnly); set on login, ~5 days, cleared on logout |
csrf_token | CSRF httpOnly cookie |
csrf_token_client | CSRF value readable by JS for the x-csrf-token header |
firebase_token | Legacy ID-token cookie name (cleared on logout; do not set or accept for auth) |
Public policy page: /cookies (src/app/cookies/page.tsx).
Preference storage (when the banner is enabled): localStorage key from config.cookies.storageKey (default shipsafe_cookie_prefs), shape { analytics: boolean, updatedAt: string }.
Config
cookies: {
nonEssentialEnabled: false, // flip true when you add analytics
policyPath: "/cookies",
storageKey: "shipsafe_cookie_prefs",
},
Components / helpers
| Piece | Path |
|---|---|
CookieConsent | src/components/ui/CookieConsent.tsx — mounted via ClientLayout in root layout |
getCookiePrefs / writeCookiePrefs | src/features/cookies/prefs.ts |
Non-essential / analytics
When you add Plausible, GA, or similar:
- Set
config.cookies.nonEssentialEnabledtotrue - Expand CSP allowlists for that vendor (Security Headers)
- Gate scripts with
getCookiePrefs(config.cookies.storageKey)?.analytics === true - Clear
localStoragefor the storage key when testing the banner
Until then, leave nonEssentialEnabled false.
Related
- CookieConsent UI doc
- Security Headers — CSP honesty note
- Pre-publish checklist — launch gates
- App routes:
/privacy,/cookies