npm package: @phygitallabs/phygital-consent
Description: Consent API, hooks, provider, and UI for the Phygital Consent Service (NCS).
Latest version: 1.0.28

# @phygitallabs/phygital-consent

Consent API, hooks, provider, and UI for the Phygital Consent Service (NCS).

## Main provider (recommended)

Use `PhygitalConsentProvider` as the single entry for consumer apps. It wraps `ConsentServiceProvider` and exposes `hasConsentPreference` + `refreshConsentPreference` so you can show/hide the cookie banner based on whether the user has already chosen a preference (stored in the `phygital_cookie_consent` cookie).

```tsx
import {
  PhygitalConsentProvider,
  usePhygitalConsent,
  CookieConsentBanner,
} from "@phygitallabs/phygital-consent";

function AppWithBanner() {
  const { hasConsentPreference, refreshConsentPreference } = usePhygitalConsent();
  const deviceId = "…"; // Consumer supplies (e.g. hashed device id).

  return (
    <>
      <YourApp />
      {!hasConsentPreference && (
        <CookieConsentBanner deviceId={deviceId} onSubmitted={refreshConsentPreference} />
      )}
    </>
  );
}

// Root layout
<PhygitalConsentProvider baseURL="https://your-consent-api.example.com">
  <AppWithBanner />
</PhygitalConsentProvider>;
```

On Accept/Reject, the banner calls the consent API, then stores the selection in the browser cookie `phygital_cookie_consent` (hashed device id + `selected_preferences`), then calls `onSubmitted` so the provider refreshes and hides the banner.

## Analytics (GA) consent

GA is allowed only when the user has submitted cookie preference and **analytics** is in `selected_preferences`. Use `isAnalyticsAllowed()` (helper) or `useIsAnalyticsAllowed()` (hook) or `usePhygitalConsent().isAnalyticsAllowed` (context). Before the GA script runs (or as the first thing in app), set gtag consent default to denied: `gtag('consent', 'default', { analytics_storage: 'denied', ad_storage: 'denied' })`. When `isAnalyticsAllowed` becomes true, call `gtag('consent', 'update', { analytics_storage: 'granted' })`. The consuming app owns all gtag calls; this package does not depend on `window` or gtag.

**Using GTM (Google Tag Manager):** Add a script in your HTML **before** the GTM container script (`gtm.js`) that initializes `dataLayer` and sets consent default to denied (see tapquest-core `getGtmConsentDefaultSnippet()` / `GTM_CONSENT_DEFAULT_HTML`). Then `GtagConsentSync` will push the consent update when the user accepts analytics.

## Cookie consent banner

One-page cookie banner with three preferences: **essential**, **analytics**, **advertising**. Reject sends only `essential`; Accept sends all three. Use inside `PhygitalConsentProvider` and pass `onSubmitted={refreshConsentPreference}` so the banner hides after submit. The consumer app must supply `deviceId` (and hash it before the API if required).

## Styles (Tailwind v4)

This package ships its own Tailwind v4 styles with the **`consent:`** prefix so they are not overridden by the consumer app’s Tailwind config.

1. **Import the built CSS** once in your app (e.g. in your root layout or `_app`):

   ```ts
   import "@phygitallabs/phygital-consent/styles";
   ```

2. **Use prefixed utilities** in any component (from this package or your app) that should use these styles:

   ```tsx
   <div className="consent:flex consent:gap-4 consent:p-4 consent:rounded-lg">...</div>
   ```

The built CSS is generated at publish time and is not processed by the consumer’s Tailwind, so the package’s styles stay consistent regardless of the app’s theme or config.