cloudflare-next-intl 0.13.1 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/src/client/components/client_extensions.js +1 -1
- package/dist/src/cookie_consent/client/components/cookie_consent_analytics.js +15 -4
- package/dist/src/cookie_consent/client/cookie_consent_provider.js +43 -16
- package/dist/src/server/components/helper_script.d.ts +5 -2
- package/dist/src/server/components/helper_script.js +22 -4
- package/dist/src/types/types.d.ts +4 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -599,6 +599,8 @@ export default setIntlConfig({
|
|
|
599
599
|
// countryHeaderNames: ["x-cf-country", "cf-ipcountry"],
|
|
600
600
|
// gdprCountries: [...], // defaults to EU/EEA + UK + Switzerland
|
|
601
601
|
// enableAnalyticsInDevMode: true, // analytics stay off in dev otherwise
|
|
602
|
+
// googleTagId: "GT-XXXXXXXX", // gtag.js in IntlHelperScript; defaults to analytics.googleAdsId
|
|
603
|
+
// googleTag: false, // turn off the IntlHelperScript Google tag
|
|
602
604
|
// autoWireDialogs: false, // opt out and render the dialogs yourself
|
|
603
605
|
// dialogProps: { acceptText: "Accept", showPrivacyPolicy: true }, // forwarded to CookieConsentDialog
|
|
604
606
|
// updateDialogProps: { closeText: "Got it", showPrivacyPolicy: true }, // forwarded to PrivacyPolicyUpdateDialog
|
|
@@ -31,7 +31,7 @@ export default function ClientExtensions({ initialAuthUser = null, skipAuthProvi
|
|
|
31
31
|
providedChildren = (_jsxs(AuthUserProvider, { initialUser: initialAuthUser, children: [children, isPerf && (_jsx(Suspense, { fallback: null, children: _jsx(AutoFirebasePerformanceEvents, {}) }))] }));
|
|
32
32
|
}
|
|
33
33
|
if (isConsent) {
|
|
34
|
-
providedChildren = (_jsxs(CookieConsentProvider, { requiresConsent: requiresConsent, cookieConsentConfig: resolvedConsent, children: [providedChildren, analyticsConfig && (_jsx(Suspense, { fallback: null, children: _jsx(CookieConsentAnalytics, { config: analyticsConfig }) })), analyticsConfig && (analyticsConfig.googleAnalyticsId || analyticsConfig.googleAdsId) && (_jsx(Suspense, { fallback: null, children: _jsx(AutoAnalyticsEvents, { config: autoAnalyticsEventsConfig ?? resolvedConsent?.autoAnalyticsEvents }) })), autoWireDialogs && (_jsxs(_Fragment, { children: [_jsx(Suspense, { fallback: null, children: _jsx(CookieConsentDialog, { ...(dialogProps ?? resolvedConsent?.dialogProps) }) }), _jsx(Suspense, { fallback: null, children: _jsx(PrivacyPolicyUpdateDialog, { ...(updateDialogProps ?? resolvedConsent?.updateDialogProps) }) })] }))] }));
|
|
34
|
+
providedChildren = (_jsxs(CookieConsentProvider, { requiresConsent: requiresConsent, cookieConsentConfig: resolvedConsent, children: [providedChildren, analyticsConfig && (_jsx(Suspense, { fallback: null, children: _jsx(CookieConsentAnalytics, { config: analyticsConfig }) })), analyticsConfig && (analyticsConfig.googleAnalyticsId || analyticsConfig.googleAdsId || (typeof analyticsConfig.googleTagId === 'string' && analyticsConfig.googleTagId)) && (_jsx(Suspense, { fallback: null, children: _jsx(AutoAnalyticsEvents, { config: autoAnalyticsEventsConfig ?? resolvedConsent?.autoAnalyticsEvents }) })), autoWireDialogs && (_jsxs(_Fragment, { children: [_jsx(Suspense, { fallback: null, children: _jsx(CookieConsentDialog, { ...(dialogProps ?? resolvedConsent?.dialogProps) }) }), _jsx(Suspense, { fallback: null, children: _jsx(PrivacyPolicyUpdateDialog, { ...(updateDialogProps ?? resolvedConsent?.updateDialogProps) }) })] }))] }));
|
|
35
35
|
}
|
|
36
36
|
return (_jsxs(_Fragment, { children: [_jsx(ClientThemeScript, {}), providedChildren] }));
|
|
37
37
|
}
|
|
@@ -34,19 +34,30 @@ export default function CookieConsentAnalytics({ config }) {
|
|
|
34
34
|
script.setAttribute('data-cf-beacon', config.cloudflareBeaconToken);
|
|
35
35
|
document.head.appendChild(script);
|
|
36
36
|
}, [granted, config.cloudflareBeaconToken]);
|
|
37
|
-
const hasGoogle = Boolean(config.googleAnalyticsId ||
|
|
37
|
+
const hasGoogle = Boolean(config.googleAnalyticsId ||
|
|
38
|
+
config.googleAdsId ||
|
|
39
|
+
config.googleAdSenseId ||
|
|
40
|
+
(typeof config.googleTagId === 'string' && config.googleTagId));
|
|
38
41
|
return (_jsxs(_Fragment, { children: [hasGoogle && (_jsx("script", { id: "cookie-consent-google-consent-mode", dangerouslySetInnerHTML: { __html: googleConsentModeBootstrapScript(config) } })), hydrated && granted && config.clarityProjectId && (_jsx(Suspense, { fallback: null, children: _jsx(ClarityScript, { projectId: config.clarityProjectId }) }))] }));
|
|
39
42
|
}
|
|
40
43
|
export function googleConsentModeBootstrapScript(config) {
|
|
41
|
-
const configCalls = [
|
|
44
|
+
const configCalls = [
|
|
45
|
+
config.googleAnalyticsId,
|
|
46
|
+
config.googleAdsId,
|
|
47
|
+
typeof config.googleTagId === 'string' ? config.googleTagId : undefined,
|
|
48
|
+
]
|
|
42
49
|
.filter(Boolean)
|
|
50
|
+
.filter((id, index, arr) => arr.indexOf(id) === index)
|
|
43
51
|
.map((id) => `gtag('config', '${id}');`)
|
|
44
52
|
.join('\n');
|
|
45
|
-
const
|
|
53
|
+
const gtagTargetId = config.googleAnalyticsId ??
|
|
54
|
+
config.googleAdsId ??
|
|
55
|
+
(typeof config.googleTagId === 'string' ? config.googleTagId : undefined);
|
|
56
|
+
const gtagLoader = gtagTargetId
|
|
46
57
|
? `(function(){
|
|
47
58
|
var s = document.createElement('script');
|
|
48
59
|
s.async = true;
|
|
49
|
-
s.src = 'https://www.googletagmanager.com/gtag/js?id=${
|
|
60
|
+
s.src = 'https://www.googletagmanager.com/gtag/js?id=${gtagTargetId}';
|
|
50
61
|
document.head.appendChild(s);
|
|
51
62
|
})();`
|
|
52
63
|
: '';
|
|
@@ -17,6 +17,10 @@ function parseConsent(raw) {
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
const defaultGdprCountriesSet = new Set(defaultGdprCountries);
|
|
20
|
+
const countryCookiePollMs = 200;
|
|
21
|
+
const countryCookieRevealMs = 2000;
|
|
22
|
+
const countryCookieMaxWaitMs = 15000;
|
|
23
|
+
const countryCookieRefreshParam = '__cfni_country';
|
|
20
24
|
export default function CookieConsentProvider({ requiresConsent: requiresConsentProp = true, cookieConsentConfig, children, }) {
|
|
21
25
|
const { consentCookieName, dateCookieName, maxAge, policyDate, privacyPolicyPath, showPrivacyPolicy, gdprCountries } = useMemo(() => {
|
|
22
26
|
const cc = requireCookieConsentConfig(cookieConsentConfig ?? config.cookieConsent);
|
|
@@ -40,25 +44,48 @@ export default function CookieConsentProvider({ requiresConsent: requiresConsent
|
|
|
40
44
|
const storedConsent = parseConsent(rawConsent);
|
|
41
45
|
const isFirstVisit = rawConsent === null;
|
|
42
46
|
setConsentState(storedConsent);
|
|
43
|
-
|
|
47
|
+
const gdprSet = gdprCountries ? new Set(gdprCountries) : defaultGdprCountriesSet;
|
|
48
|
+
const applyCountryCookie = () => {
|
|
44
49
|
const countryCookie = getCookie(countryCookieKey);
|
|
45
|
-
if (countryCookie)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
if (!countryCookie)
|
|
51
|
+
return false;
|
|
52
|
+
setRequiresConsent(gdprSet.has(countryCookie));
|
|
53
|
+
return true;
|
|
54
|
+
};
|
|
55
|
+
let pollId;
|
|
56
|
+
let revealId;
|
|
57
|
+
let stopId;
|
|
58
|
+
const stopPolling = () => {
|
|
59
|
+
clearInterval(pollId);
|
|
60
|
+
clearTimeout(revealId);
|
|
61
|
+
clearTimeout(stopId);
|
|
62
|
+
};
|
|
63
|
+
if (!requiresConsentProp || applyCountryCookie()) {
|
|
64
|
+
setIsMounted(true);
|
|
51
65
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
else {
|
|
67
|
+
fetch(`${window.location.pathname}?${countryCookieRefreshParam}=${Date.now()}`, { method: 'HEAD', cache: 'no-store', credentials: 'same-origin' })
|
|
68
|
+
.catch(() => undefined);
|
|
69
|
+
pollId = setInterval(() => {
|
|
70
|
+
if (!applyCountryCookie())
|
|
71
|
+
return;
|
|
72
|
+
stopPolling();
|
|
73
|
+
setIsMounted(true);
|
|
74
|
+
}, countryCookiePollMs);
|
|
75
|
+
revealId = setTimeout(() => setIsMounted(true), countryCookieRevealMs);
|
|
76
|
+
stopId = setTimeout(stopPolling, countryCookieMaxWaitMs);
|
|
77
|
+
}
|
|
78
|
+
if (!isFirstVisit && policyDate) {
|
|
79
|
+
const storedDateRaw = getCookie(dateCookieName);
|
|
80
|
+
if (!storedDateRaw) {
|
|
81
|
+
setCookie({ name: dateCookieName, value: policyDate.toISOString(), maxAge });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const storedDate = new Date(storedDateRaw);
|
|
85
|
+
setPrivacyPolicyUpdated(!Number.isNaN(storedDate.getTime()) && storedDate < policyDate);
|
|
86
|
+
}
|
|
59
87
|
}
|
|
60
|
-
|
|
61
|
-
setPrivacyPolicyUpdated(!Number.isNaN(storedDate.getTime()) && storedDate < policyDate);
|
|
88
|
+
return stopPolling;
|
|
62
89
|
}, [consentCookieName, dateCookieName, maxAge, policyDate, requiresConsentProp, gdprCountries]);
|
|
63
90
|
const setConsent = useCallback((value) => {
|
|
64
91
|
if (value === null) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { defaultReloadHtml } from 'cloudflare-next-intl-errors/staleDeployScripts';
|
|
3
3
|
export { defaultReloadHtml };
|
|
4
|
-
export
|
|
4
|
+
export interface HelperScriptProps {
|
|
5
5
|
locale?: string;
|
|
6
|
-
|
|
6
|
+
googleTag?: boolean;
|
|
7
|
+
googleTagId?: string | false;
|
|
8
|
+
}
|
|
9
|
+
export default function HelperScript({ locale, googleTag, googleTagId, }?: HelperScriptProps): React.JSX.Element;
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import CoreHelperScript from 'cloudflare-next-intl-intl/internal/helperScript';
|
|
3
3
|
import ThemeScript from 'cloudflare-next-intl-theme/ThemeScript';
|
|
4
4
|
import StaleDeployScripts, { defaultReloadHtml } from 'cloudflare-next-intl-errors/staleDeployScripts';
|
|
5
5
|
import config from '../../config/intl_config.js';
|
|
6
6
|
export { defaultReloadHtml };
|
|
7
|
-
export default function HelperScript({ locale }) {
|
|
7
|
+
export default function HelperScript({ locale, googleTag, googleTagId, } = {}) {
|
|
8
8
|
const analytics = config.cookieConsent?.analytics;
|
|
9
|
-
const
|
|
9
|
+
const cookieConsent = config.cookieConsent;
|
|
10
|
+
const isGoogleTagExplicitlyOff = googleTag === false ||
|
|
11
|
+
googleTagId === false ||
|
|
12
|
+
analytics?.googleTag === false ||
|
|
13
|
+
analytics?.googleTagId === false ||
|
|
14
|
+
cookieConsent?.googleTag === false ||
|
|
15
|
+
cookieConsent?.googleTagId === false;
|
|
16
|
+
const rawTagId = (typeof googleTagId === 'string' ? googleTagId : undefined) ||
|
|
17
|
+
(typeof analytics?.googleTagId === 'string' ? analytics.googleTagId : undefined) ||
|
|
18
|
+
(typeof cookieConsent?.googleTagId === 'string' ? cookieConsent.googleTagId : undefined) ||
|
|
19
|
+
analytics?.googleAdsId;
|
|
20
|
+
const resolvedGoogleTagId = !isGoogleTagExplicitlyOff ? rawTagId : undefined;
|
|
21
|
+
const shouldRenderGoogleTag = Boolean(resolvedGoogleTagId && !isGoogleTagExplicitlyOff);
|
|
22
|
+
const hasGoogle = !!(analytics?.googleAnalyticsId ||
|
|
23
|
+
analytics?.googleAdsId ||
|
|
24
|
+
analytics?.googleAdSenseId ||
|
|
25
|
+
shouldRenderGoogleTag);
|
|
10
26
|
const hasClarity = !!analytics?.clarityProjectId;
|
|
11
27
|
const hasFirebase = !!config.firebaseAuth;
|
|
12
28
|
const hasTurnstile = !!config.firebaseAuth?.appCheck?.turnstileSiteKey;
|
|
@@ -22,5 +38,7 @@ export default function HelperScript({ locale }) {
|
|
|
22
38
|
const preconnectOrigins = [];
|
|
23
39
|
if (hasTurnstile)
|
|
24
40
|
preconnectOrigins.push('https://challenges.cloudflare.com');
|
|
25
|
-
return (_jsxs(CoreHelperScript, { locale: locale, prefetchOrigins: prefetchOrigins.length > 0 ? prefetchOrigins : undefined, preconnectOrigins: preconnectOrigins.length > 0 ? preconnectOrigins : undefined, children: [_jsx(ThemeScript, {}), _jsx(StaleDeployScripts, { reloadHtml: config.errorHandling?.staleDeployReloadHtml })
|
|
41
|
+
return (_jsxs(CoreHelperScript, { locale: locale, prefetchOrigins: prefetchOrigins.length > 0 ? prefetchOrigins : undefined, preconnectOrigins: preconnectOrigins.length > 0 ? preconnectOrigins : undefined, children: [_jsx(ThemeScript, {}), _jsx(StaleDeployScripts, { reloadHtml: config.errorHandling?.staleDeployReloadHtml }), shouldRenderGoogleTag && (_jsxs(_Fragment, { children: [_jsx("script", { async: true, src: `https://www.googletagmanager.com/gtag/js?id=${resolvedGoogleTagId}` }), _jsx("script", { id: "google-tag-init", dangerouslySetInnerHTML: {
|
|
42
|
+
__html: `window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', '${resolvedGoogleTagId}');`,
|
|
43
|
+
} })] }))] }));
|
|
26
44
|
}
|
|
@@ -20,6 +20,8 @@ export interface CookieConsentRoutingConfig {
|
|
|
20
20
|
privacyPolicyDateCookieName?: string;
|
|
21
21
|
cookieMaxAge?: number;
|
|
22
22
|
autoWireAnalytics?: boolean;
|
|
23
|
+
googleTag?: boolean;
|
|
24
|
+
googleTagId?: string | false;
|
|
23
25
|
analytics?: CookieConsentAnalyticsConfig;
|
|
24
26
|
getAnalytics?: () => CookieConsentAnalyticsConfig | Promise<CookieConsentAnalyticsConfig>;
|
|
25
27
|
autoAnalyticsEvents?: AutoAnalyticsEventsConfig;
|
|
@@ -55,6 +57,8 @@ export interface CookieConsentAnalyticsConfig {
|
|
|
55
57
|
cloudflareBeaconToken?: string;
|
|
56
58
|
googleAnalyticsId?: string;
|
|
57
59
|
googleAdsId?: string;
|
|
60
|
+
googleTagId?: string | false;
|
|
61
|
+
googleTag?: boolean;
|
|
58
62
|
googleAdSenseId?: string;
|
|
59
63
|
clarityProjectId?: string;
|
|
60
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudflare-next-intl",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "Optimized Next Intl Package Special for App Router and Cloudflare",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -364,7 +364,7 @@
|
|
|
364
364
|
"homepage": "https://github.com/demian-ilnytskyi/cloudflare-next-intl#readme",
|
|
365
365
|
"dependencies": {
|
|
366
366
|
"@microsoft/clarity": "^1.0.2",
|
|
367
|
-
"cloudflare-next-intl-auth": "^0.
|
|
367
|
+
"cloudflare-next-intl-auth": "^0.3.0",
|
|
368
368
|
"cloudflare-next-intl-db": "^0.3.0",
|
|
369
369
|
"cloudflare-next-intl-db-codegen": "^0.1.4",
|
|
370
370
|
"cloudflare-next-intl-errors": "^0.1.0",
|