@consentry/next
Version:
Next.js + React integration layer for the Consentry SDK. Manages cookie preferences, script injection, and analytics sync.
153 lines (149 loc) • 4.8 kB
JavaScript
// src/Scripts.tsx
import Script from "next/script";
import React from "react";
// src/ConsentManagerProvider.tsx
import { useEffect, useState, createContext, useContext } from "react";
import {
fallbackDefaults,
getConsentPreferences,
setConsentPreferences,
updateConsentSettings
} from "@consentry/core";
import { jsx, jsxs } from "react/jsx-runtime";
var ConsentManagerContext = createContext(void 0);
var ConsentManagerProvider = ({
config,
children
}) => {
const [cookiePreferences, setCookiePreferencesState] = useState({
...fallbackDefaults,
...config.defaults
});
const [showConsentBanner, setShowConsentBanner] = useState(false);
const [isConsentKnown, setIsConsentKnown] = useState(false);
useEffect(() => {
const saved = getConsentPreferences();
if (saved) {
setCookiePreferencesState(saved);
setShowConsentBanner(false);
} else {
setShowConsentBanner(true);
}
setIsConsentKnown(true);
}, []);
const setCookiePreferences = (prefs) => {
setCookiePreferencesState(prefs);
setConsentPreferences(prefs);
setShowConsentBanner(false);
const { performance, advertising, social } = prefs;
updateConsentSettings("update", {
analytics_storage: performance ? "granted" : "denied",
ad_storage: advertising ? "granted" : "denied",
ad_user_data: advertising ? "granted" : "denied",
ad_personalization: social ? "granted" : "denied"
});
};
return /* @__PURE__ */ jsxs(
ConsentManagerContext.Provider,
{
value: {
cookiePreferences,
setCookiePreferences,
showConsentBanner,
isConsentKnown
},
children: [
/* @__PURE__ */ jsx(Scripts, { config }),
children
]
}
);
};
var useConsentManager = () => {
const ctx = useContext(ConsentManagerContext);
if (!ctx) {
throw new Error("useConsentManager must be used within a ConsentManagerProvider");
}
const { cookiePreferences, setCookiePreferences, showConsentBanner, isConsentKnown } = ctx;
const setCategoryConsent = (category, value) => {
setCookiePreferences({
...cookiePreferences,
[category]: value
});
};
const hasConsentedTo = (category) => cookiePreferences[category] === true;
return {
cookiePreferences,
setCookiePreferences,
setCategoryConsent,
hasConsentedTo,
showConsentBanner,
isConsentKnown
};
};
// src/Scripts.tsx
import { getAllowedScripts } from "@consentry/core";
// src/utils/extractScriptTagAttrs.ts
function extractScriptTagAttrs(html) {
if (typeof window === "undefined") return null;
try {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const scriptEl = doc.querySelector("script");
if (!scriptEl) return null;
const src = scriptEl.getAttribute("src") || void 0;
const attrs = {};
for (const attr of Array.from(scriptEl.attributes)) {
attrs[attr.name] = attr.value;
}
return { src, attrs };
} catch (e) {
console.warn("[consentry] Failed to parse script content:", e);
return null;
}
}
// src/Scripts.tsx
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
function Scripts({ config }) {
const { cookiePreferences, isConsentKnown } = useConsentManager();
const debug = config.debug ?? false;
if (!isConsentKnown) return null;
const allowedScripts = getAllowedScripts(config, cookiePreferences, debug);
const handleScriptError = (id, src) => {
console.warn(`[consentry] Script "${id}" failed to load.`, { src });
};
return /* @__PURE__ */ jsx2(Fragment, { children: allowedScripts.map((script) => {
let parsed = null;
if (script.content?.trim().startsWith("<script")) {
parsed = extractScriptTagAttrs(script.content);
if (parsed) {
if (debug) {
console.warn(
`[consentry] Script "${script.id}" used <script> in content. Parsed as src-based script for safety.`
);
}
}
}
const isInline = !parsed && script.content;
return /* @__PURE__ */ jsxs2(React.Fragment, { children: [
/* @__PURE__ */ jsx2(
Script,
{
id: script.id,
strategy: script.strategy || "afterInteractive",
src: parsed?.src || script.src,
dangerouslySetInnerHTML: isInline ? { __html: script.content } : void 0,
onError: () => handleScriptError(script.id, parsed?.src || script.src),
...parsed?.attrs || script.attributes || {}
}
),
script.noscript && /* @__PURE__ */ jsx2("noscript", { dangerouslySetInnerHTML: { __html: script.noscript } })
] }, script.id);
}) });
}
export {
ConsentManagerProvider,
Scripts,
useConsentManager
};
//# sourceMappingURL=index.mjs.map