@gocharles/axeptio-then-segment
v4.1.0
Published
Axeptio CMP + Segment consent-tools wrapper with destination blocking and Google Consent Mode defaults
Downloads
405
Maintainers
Readme
@gocharles/axeptio-then-segment
Axeptio (CMP) + Segment (@segment/analytics-next) + Google Consent Mode defaults (denied until the CMP completes).
Uses @segment/analytics-consent-tools in opt-in mode (GDPR): unconsented device-mode destinations are blocked from initializing entirely. Category-to-destination mappings are configured in the Segment dashboard (Privacy → Consent Management) — no hardcoded destination list in code.
How it works
- Google Consent Mode defaults are set to
deniedbefore anything loads. - Axeptio CMP is injected and displayed to the user.
- Segment
analytics.load()is called immediately, but the consent wrapper delays initialization until Axeptio firescookies:complete(user accepts or refuses). - On consent,
getCategories()returns the Axeptio choices asRecord<string, boolean>(meta keys like$$googleConsentModeare stripped). - Consent-tools uses the category-to-destination mappings from the Segment CDN settings to block unconsented device-mode destinations from loading (e.g. Facebook Pixel scripts are never fetched if
targeted_advertisingis refused). - If the user re-opens the CMP and changes preferences,
registerOnConsentChangedfires aSegment Consent Preference Updatedevent and destinations are re-evaluated.
Consumption (public npm)
Published as @gocharles/axeptio-then-segment on the public registry. No .npmrc or token is required to install.
Apps with a bundler (Vite, Gatsby, webpack, etc.)
npm install @gocharles/axeptio-then-segmentimport { initAxeptioThenSegment } from '@gocharles/axeptio-then-segment'CommonJS:
const { initAxeptioThenSegment } = require('@gocharles/axeptio-then-segment')Types are included (dist/index.d.ts, dist/index.d.mts). Pin a semver range in package.json (e.g. ^4.1.0 vs exact version).
Browser only (no build step)
Load the IIFE from a CDN that mirrors npm (path inside the package: dist/axeptio-then-segment.iife.min.js).
jsDelivr (pin the version in production):
https://cdn.jsdelivr.net/npm/@gocharles/[email protected]/dist/axeptio-then-segment.iife.min.jsunpkg (equivalent):
https://unpkg.com/@gocharles/[email protected]/dist/axeptio-then-segment.iife.min.jsThen call the global (same options as initAxeptioThenSegment):
<script src="https://cdn.jsdelivr.net/npm/@gocharles/[email protected]/dist/axeptio-then-segment.iife.min.js" crossorigin="anonymous"></script>
<script>
var analytics = AxeptioThenSegment.init({
axeptioClientId: '…',
segmentWriteKey: '…',
cookiesVersion: '…',
trackInitialPageView: true,
})
// `analytics` is the wrapped instance; `window.analytics` is the same object when using defaults.
</script>Using @latest in the URL is possible but any new publish will immediately affect that URL; prefer a fixed version for production pages.
Alternatives
- GitHub Release asset (attached by CI on each version tag):
https://github.com/gocharles/axeptio-then-segment/releases/latest/download/axeptio-then-segment.iife.min.jsor a pinned URL underreleases/download/vX.Y.Z/….
API
initAxeptioThenSegment(config) (and AxeptioThenSegment.init in the IIFE) returns the wrapped AnalyticsBrowser instance in the browser. In SSR (no window / document), it returns undefined.
The type AnalyticsBrowser is re-exported from @segment/analytics-next for convenience. Global Window is augmented with optional analytics when you import this package (see exposeOnWindow below).
| Option | Required | Description |
|--------|----------|-------------|
| axeptioClientId | yes | Your Axeptio client ID. |
| segmentWriteKey | yes | Your Segment source write key. |
| cookiesVersion | yes | Axeptio cookies / project configuration identifier from your Axeptio back-office. |
| cookieDomain | no | Domain for the Axeptio consent cookie (e.g. .example.com). |
| trackInitialPageView | no | Queue analytics.page() when Segment first loads after the CMP completes. Common on static HTML hosts. |
| defaultGoogleConsentMode | no | Override the default Google Consent Mode payload (defaults to all denied). |
| exposeOnWindow | no | Default true. After withAxeptio(analytics) and before analytics.load(...), assigns window.analytics = analytics so legacy window.analytics.track / identify / page / user() calls use the consent-aware wrapper. Set to false to leave window.analytics untouched. |
Migration v3 → v4 (and patch v4.0.x)
- v4 switches from the historical Segment snippet to
@segment/analytics-next(AnalyticsBrowser) behind the same Axeptio + consent-tools flow (opt-in, device-mode blocking unchanged). - In v4.0.x,
initAxeptioThenSegmentdid not assignwindow.analytics, so code that gated ontypeof window.analytics !== 'undefined'or calledwindow.analytics.track(...)could silently stop sending events. - From v4.1.0 onward,
exposeOnWindowdefaults totrue, restoring the legacy global after the consent wrapper is applied and beforeload, without changingwithAxeptio/createWrapperbehavior. - Recommended: rely on the returned instance (
const analytics = initAxeptioThenSegment({...})) instead of the global, and useexposeOnWindow: falseif you must avoid globals (multiple instances, tests, strict isolation).
Destination blocking
Destination blocking is enforced client-side by @segment/analytics-consent-tools:
- In opt-in mode (GDPR), device-mode destinations whose consent categories are not accepted by the user are never loaded — their scripts are not injected, no pixels fire, no network requests are made.
- Mappings between consent categories and destinations are managed in the Segment dashboard under Privacy → Consent Management. No code changes are needed when adding or removing destinations.
- To verify: open DevTools → Network after refusing all categories. You should see zero destination scripts (no
fbevents.js, no Google Ads tags, etc.).
Local build
npm ci
npm run build| Output | Role |
|--------|------|
| dist/index.mjs, dist/index.js | ESM / CJS |
| dist/index.d.ts, dist/index.d.mts | Types |
| dist/axeptio-then-segment.iife.min.js | Script tag / CDN (bundles analytics-next + consent-tools) |
Examples
See examples/.
Publishing (maintainers)
Automated (GitHub Actions)
- In the GitHub repo Settings → Secrets and variables → Actions, add
NPM_TOKEN: an npm access token able to publish@gocharles/axeptio-then-segment(e.g. Automation token, or Granular with Read and write on this package and Bypass 2FA if your account uses 2FA). - Ensure
versioninpackage.jsonmatches the release you are about to tag. - Push a tag:
git tag v4.1.0 && git push origin v4.1.0(same version as inpackage.json, with avprefix).
The release workflow runs npm publish --access public and creates a GitHub Release with the IIFE attached.
Manual
npm login
npm publish --access public(prepublishOnly runs npm run build automatically.)
403 Forbidden — "Two-factor authentication or granular access token with bypass 2fa…"
npm blocks publish unless either:
You pass a one-time code (account with 2FA enabled):
npm publish --access public --otp=123456Replace
123456with the current code from your authenticator app (valid for a short time).CI / token — use an Automation token, or a Granular token with Read and write on
@gocharles/axeptio-then-segmentand Bypass 2FA enabled (npm recommends Trusted Publishing long term).
Also ensure your npm user is a member of the @gocharles org with permission to publish this package.
