@vstx/vxcookies
v1.2.5
Published
Cookie consent via init() only (<vx-cookies> web component).
Maintainers
Readme
@vstx/vxcookies
Cookie consent UI for the browser: a single init() call registers the <vx-cookies> custom element and mounts the banner. React 18+ is a peer dependency; styles are bundled into the JS build (injected at runtime) no @vstx/vxcookies/style.css needed.
Installation
React applications
npm install @vstx/vxcookiesUse React 18+ and React DOM 18+ in the host app. The published package expects them as peers (not bundled).
Baukasten - SmartVX
There is no separate “SmartVX npm entry”: the repo includes a second production build that outputs a self-contained ESM bundle (React included) into the SmartVX static tree next to this project, configured in vite/vite.config.smartvx.js. Run npm publish from this repository (or just npm run build if the changes are only needed in SmartVX) when you need to refresh that output; it is written under layouts/vx/http-static/vxcookies/dist/ in the SmartVX tree (see vite/vite.config.smartvx.js). The bundle is loaded like any other static script (e.g. via vxcookies-bootstrap.js on platforms 2107/2108).
Note for development in SmartVX: In each VX PFM layout, http-static/vxcookies is a symlink to the shared folder layouts/vx/http-static/vxcookies, so the same dist/ and vxcookies-bootstrap.js are served for all PFMs.
-> There are no duplicates. If you need to adjust something in vxcookies-bootstrap.js you'll have to do it in the shared location outside of the respective PFM layout.
Usage
Import the default export — a plain object with init and the constants below.
Exported constants
Use these for type-safe option values instead of hard-coded strings.
| Constant | Role |
| ------------------------------ | --------------------------------------------------------------------------------------- |
| CookieCategories | NECESSARY → 'necessary', FUNCTIONAL → 'functional', ANALYTICS → 'analytics' |
| AvailableLocales | DE → 'de' (default), EN → 'en', ES → 'es' |
| AvailableThemes | DARK → 'dark' (default), LIGHT → 'light' |
| DefaultBreakpoints | mobile: 768, tablet: 992, desktop: 1200 (aligned with vxone) |
| CookieSameSiteAttributes | LAX → 'Lax', NONE → 'None' |
init(options)
Call once after the document is ready (the library also waits for DOMContentLoaded if needed). Repeated calls when the component already exists are ignored with a console warning.
| Option | Description |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| locale | Language code: 'de', 'en', or 'es'. Prefer AvailableLocales. Default: German (de). |
| platform | { name, logoUrl } for branding. In Baukasten-style setups where name or logo may be missing, the UI falls back to sensible defaults (e.g. generic title / placeholder behaviour). |
| theme | 'light' or 'dark'. Prefer AvailableThemes. Default: dark. |
| breakpoints | { mobile, tablet, desktop } in pixels. Merged with DefaultBreakpoints if you only override part of it. |
| onFirstAccept | Optional callback when consent is applied and the analytics category is included in the accepted set (e.g. “Accept all” or saving settings with analytics on). Use for extra host logic (e.g. tags); the library already persists consent and updates gtag when applicable. |
| onPreferencesChange | Optional callback when the user saves changes in the settings modal and at least one category changed. Same idea: additional host logic, not required for storing consent. |
| dataProtectionLegalTextGetter | Optional async-friendly function that returns HTML for the in-banner data protection section. If omitted, that panel stays empty and no error is thrown. |
| selectors | Optional stable hook strings for the consent UI (e.g. values aligned with data-testid in Playwright). Merged with the built-in defaults (tables below) so partial overrides keep working. The package does not export the selector map; hosts use the documented defaults when choosing locators, or pass overrides via init({ selectors }). |
Selectors (init({ selectors }), Playwright)
Pass an object with the same shape as the tables below so tests can target the same data-testid values the UI renders. init({ selectors }) is merged with those built-in defaults: top-level keys override the banner map, and SETTINGS is merged shallowly with the built-in SETTINGS object. Extra top-level keys you add are kept for internal resolution.
Banner (main consent)
| Key | Default data-testid |
| --- | --- |
| ACCEPT_ALL_BUTTON | cookie-consent-accept-all |
| OPEN_SETTINGS_BUTTON | cookie-consent-open-settings-button |
| DATA_PROTECTION_TOGGLER | cookie-consent-open-data-protection-link |
| RTA_LINK | cookie-consent-rta-link |
Modal settings (SETTINGS)
| Key | Default data-testid |
| --- | --- |
| SETTINGS.CLOSE_BUTTON | cookie-consent-settings-close-button |
| SETTINGS.ESSENTIAL_INFO_TOGGLER | cookie-consent-settings-essential-info-toggler |
| SETTINGS.FUNCTIONAL_INFO_TOGGLER | cookie-consent-settings-functional-info-toggler |
| SETTINGS.FUNCTIONAL_SWITCH | cookie-consent-settings-category-functional-switch |
| SETTINGS.ANALYTICS_INFO_TOGGLER | cookie-consent-settings-analytics-info-toggler |
| SETTINGS.ANALYTICS_SWITCH | cookie-consent-settings-category-analytics-switch |
| SETTINGS.DATA_PROTECTION_LINK | cookie-consent-settings-data-protection-link |
| SETTINGS.ACCEPT_ALL_BUTTON | cookie-consent-settings-accept-all-button |
| SETTINGS.REJECT_ALL_BUTTON | cookie-consent-settings-reject-all-button |
| SETTINGS.SAVE_BUTTON | cookie-consent-settings-save-button |
Omit selectors entirely if the defaults are fine. Partial overrides are supported (e.g. only SETTINGS.SAVE_BUTTON, or a single banner key like ACCEPT_ALL_BUTTON).
Example (React / ESM)
import vxcookies from '@vstx/vxcookies';
vxcookies.init({
locale: vxcookies.AvailableLocales.DE,
theme: vxcookies.AvailableThemes.DARK,
// Optional Playwright hooks: omit to use built-in defaults; partial objects are merged.
// selectors: { SETTINGS: { SAVE_BUTTON: 'my-save' } },
platform: {
name: 'Heidi Live - Die schönsten Berge Deutschlands',
logoUrl: './assets/heidi.png',
},
dataProtectionLegalTextGetter: () => Promise.resolve('<p>…</p>'),
onFirstAccept: (data) => {
/* e.g. trigger measurement tools when analytics is allowed */
},
onPreferencesChange: (consent, changedCategories) => {
/* e.g. react to category toggles */
},
});Development
Environment
Create .env.local at the project root (this file is gitignored):
| Variable | Purpose |
| --------------- | --------------------------------------------------- |
| VITE_HOST | Host passed to the Vite dev server (server.host). |
| VITE_PORT | Port for the dev server. |
Playground
The playground/ directory is gitignored by default: each developer keeps a local playground. Point Vite at it via vite.config.js (root: playground). Run npm run dev to work on the library with HMR.
Tip: You can align playground/index.html with scripts/toggle-is-dev.js (e.g. a data-is-dev flag) to switch between live source and a built ./dist bundle without hand-editing HTML each time.
Styles
Components use Less. Shared breakpoint-related defaults mirror vxone; keep visual tokens consistent with that system when adjusting variables.
Build configuration
| File | Purpose |
| --------------------------------- | --------------------------------------------------------------------------------------------------- |
| vite.config.js | Dev server + playground; library build to dist/ (ESM + CJS, React external). |
| vite/vite.config.smartvx.js | Bundled SmartVX drop (React internal) into the SmartVX http-static path configured there. |
npm run build # library dist + SmartVX bundle
npm run dev # playgroundAfter making changes (release flow)
When you ship a new version of this library, the downstream repos usually need to be updated in order. A typical sequence:
1. In vxcookies (this repo)
Implement and test your changes (
npm run dev, thennpm run buildto confirm both outputs succeed).Bump the version in
package.jsonfollowing semver (e.g. patch for fixes, minor for backwards-compatible features).Publish to npm:
npm publishprepublishOnlyrunsnpm run build, so the tarball always contains a freshdist/(peer-React build plus the SmartVX bundle copied next door if that path exists).
2. In vxone
Pull in the new release so React apps and tooling resolve the updated package:
npm install @vstx/vxcookies@latestCommit the lockfile / package.json change as vxone's workflow requires.
3. In SmartVX
The self-contained bundle under http-static/vxcookies/dist/ is produced when you run npm publish in vxcookies (with the SmartVX repo checked out beside it, as configured in Vite). After that:
Review the diff in SmartVX (only the static assets you expect should change).
Commit and push, for instance:
git add layouts/vx/http-static/vxcookies/dist/ git commit -m "chore: update vxcookies bundle" git push
Roadmap
- Near term: migrate this codebase to TypeScript for clearer public types and safer refactors.
License
MIT © Campoint / VSTX
Links
Made with ❤️ by CMPNT for VSTX / Baukasten.
