AbsoluteJS

Consent

@absolutejs/consentv0.2.1betaCommerce & Growth

Region-aware tracking consent: opt-out where the law allows it, opt-in where it requires it, Global Privacy Control, and IP-to-country resolution.

#Installation

BASH
bun add @absolutejs/consent

#Capabilities

Overview

Region-aware tracking consent for AbsoluteJS apps.

Opt-out where the law allows it, opt-in where it requires it. The

default rules give confirmed US visitors tracking-on with a notice and a way to opt out, and everyone else — the EEA, the UK, Switzerland, every other country, and anyone whose location is unknown — an opt-in prompt with everything off until they choose.

Show 7 more

Global Privacy Control. A Sec-GPC: 1 request or

navigator.globalPrivacyControl turns opt-out defaults off.

Location without a CDN. An IP→country index built from the free DB-IP

Lite database, downloaded and cached by the server, with the browser time zone as a fallback. A trusted CDN country header can be used instead.

Decisions follow the account. A choice saved on one device can be

applied on another; the newer decision always wins.

This package decides defaults. It is not legal advice; choose rules with counsel for the jurisdictions you serve.

Browser

Decisions persist in localStorage under absolute-consent. Pass migrate to read an older storage format, storage: null for memory only.

Server

Only name headers your own proxy overwrites. X-Forwarded-For entries left of your trusted hops, and CDN country headers your edge does not set, are client-controlled.

The resolver loads the newest cached database, downloads the current month from DB-IP when the cache is missing or older than 35 days (falling back to the previous month early in a month), indexes it in chunks that yield to the event loop, and returns null until it has loaded — never blocking a request on the network.

Attribution

Show 1 more

DB-IP Lite is licensed under CC BY 4.0. Where you disclose the lookup (for example your privacy policy), include: IP Geolocation by DB-IP.

Rules

OPT_IN_REQUIRED_COUNTRIES (EEA + GB + CH) is exported for apps that choose the inverse policy: opt-out everywhere except those countries.

Outcomes

What you can build

Overview

Region-aware tracking consent for AbsoluteJS apps.

Browser

Decisions persist in localStorage under absolute-consent. Pass migrate to read an older storage format, storage: null for memory only.

Server

Only name headers your own proxy overwrites. X-Forwarded-For entries left of your trusted hops, and CDN country headers your edge does not set, are client-controlled.

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/consent version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/consent example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#Browser

Partial snippet

Working example for Browser.

TS
import { createConsentStore, readGpc, readTimeZone, resolveRegion } from '@absolutejs/consent';

const store = createConsentStore({
	categories: ['analytics', 'marketing'],
	gpc: readGpc(),
	// Seed from SSR (see below) so the right UI renders on first paint;
	// otherwise fall back to the browser time zone.
	region: ssrRegion ?? resolveRegion({ timeZone: readTimeZone() })
});

store.subscribe((state) => {
	if (state.choices.analytics) startAnalytics();
	else stopAnalytics();
});

store.getState().needsPrompt; // opt-in region, undecided → show the banner
store.getState().needsNotice; // opt-out region, undecided → show a notice
store.acceptAll();
store.rejectAll();
store.decide({ analytics: true });
store.dismissNotice(); // hides the notice, records no decision
store.applyRemote({ choices: { analytics: false }, decidedAt }); // from the account

#Server

Partial snippet

Working example for Server.

TS
import { createDbIpCountryResolver, resolveRequestRegion } from '@absolutejs/consent/server';

const geo = createDbIpCountryResolver({ cacheDir: '.cache/geo', onError: console.error });
void geo.ready();

const region = resolveRequestRegion(request.headers, {
	lookup: geo.lookup,
	// nginx: proxy_set_header X-Real-IP $remote_addr;
	trustedHeader: 'x-real-ip'
});
// { country: 'US', regime: 'opt-out', source: 'country', gpc: false }

#Public entry points

Supported entry points declared by this project’s package manifest. Internal dist paths are not part of the package contract.

Public package entry point declared in package.json.

@absolutejs/consent@absolutejs/consent/package.json@absolutejs/consent/server

#Package commands

Scripts declared by this project’s package manifest.

bun run buildrm -rf dist && bun build src/index.ts --outdir dist --root ./src --target=browser --format=esm && bun build src/server.ts --outdir dist --root ./src --target=node --format=esm && tsc --emitDeclarationOnly --project tsconfig.json
bun run check:packageabsolute-changelog check
bun run testbun test
bun run typechecktsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

21 symbols