keystone-design-bootstrap 1.0.76 → 1.0.78
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/package.json
CHANGED
package/src/lib/server-api.ts
CHANGED
|
@@ -81,6 +81,8 @@ export function getMetaPixelId(adsConfig: { meta_pixel_id?: string } | null | un
|
|
|
81
81
|
export type AnalyticsConfig = {
|
|
82
82
|
/** PostHog project API key — platform-wide, from POSTHOG_API_KEY env var on the Rails server. */
|
|
83
83
|
posthog_api_key?: string;
|
|
84
|
+
/** Per-site GTM container ID (e.g. GTM-ABC123), provisioned by Keystone. */
|
|
85
|
+
gtm_container_public_id?: string;
|
|
84
86
|
/**
|
|
85
87
|
* Environment identifier from KEYSTONE_ENV on the Rails server (e.g. "production", "staging",
|
|
86
88
|
* "development"). Registered as a PostHog super property on every event so the sync job can
|
|
@@ -102,6 +104,13 @@ export function getPostHogApiKey(analyticsConfig: AnalyticsConfig | null | undef
|
|
|
102
104
|
return str !== '' && str !== 'null' ? str : null;
|
|
103
105
|
}
|
|
104
106
|
|
|
107
|
+
/** Extract GTM container ID from analytics config for use with <GoogleTagManager containerId={...} />. */
|
|
108
|
+
export function getGtmContainerPublicId(analyticsConfig: AnalyticsConfig | null | undefined): string | null {
|
|
109
|
+
const value = analyticsConfig?.gtm_container_public_id;
|
|
110
|
+
const str = value != null && value !== '' ? String(value).trim() : '';
|
|
111
|
+
return str !== '' && str !== 'null' && /^GTM-[A-Z0-9]+$/i.test(str) ? str : null;
|
|
112
|
+
}
|
|
113
|
+
|
|
105
114
|
/** Extract environment string from analytics config for use with <PostHogProvider environment={...} />. */
|
|
106
115
|
export function getKeystoneEnvironment(analyticsConfig: AnalyticsConfig | null | undefined): string {
|
|
107
116
|
return analyticsConfig?.environment?.trim() || 'development';
|
|
@@ -3,7 +3,13 @@ import type { Metadata } from 'next';
|
|
|
3
3
|
|
|
4
4
|
import { HeaderNavigation, FooterHome } from '../../design_system/sections';
|
|
5
5
|
import { ThemeProvider } from '../../contexts';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
MetaPixel,
|
|
8
|
+
MetaPixelTracker,
|
|
9
|
+
PostHogProvider,
|
|
10
|
+
KeystoneAnalyticsTracker,
|
|
11
|
+
GoogleTagManager,
|
|
12
|
+
} from '../../tracking';
|
|
7
13
|
import { ChatWidget } from '../../design_system/components/ChatWidget';
|
|
8
14
|
import { FormDefinitionsProvider } from '../contexts/form-definitions';
|
|
9
15
|
import { KeystoneSSRProvider } from '../providers/ssr-provider';
|
|
@@ -18,6 +24,7 @@ import {
|
|
|
18
24
|
getMetaPixelId,
|
|
19
25
|
getAnalyticsConfig,
|
|
20
26
|
getPostHogApiKey,
|
|
27
|
+
getGtmContainerPublicId,
|
|
21
28
|
getKeystoneEnvironment,
|
|
22
29
|
} from '../../lib/server-api';
|
|
23
30
|
|
|
@@ -111,7 +118,7 @@ function buildNavigationWithDynamicData(
|
|
|
111
118
|
* Note: Next's `export const metadata` must remain in the site/app.
|
|
112
119
|
* This component focuses on:
|
|
113
120
|
* - fetching shared data
|
|
114
|
-
* - injecting Meta Pixel (from ads_config) and PostHog (from analytics_config)
|
|
121
|
+
* - injecting Meta Pixel (from ads_config), GTM, and PostHog (from analytics_config)
|
|
115
122
|
* - applying theme
|
|
116
123
|
* - rendering Header + Footer
|
|
117
124
|
* - rendering ChatWidget gated by `companyInformation.chat_enabled`
|
|
@@ -150,6 +157,7 @@ export async function KeystoneRootLayout(props: {
|
|
|
150
157
|
|
|
151
158
|
const metaPixelId = getMetaPixelId(adsConfig);
|
|
152
159
|
const posthogApiKey = getPostHogApiKey(analyticsConfig);
|
|
160
|
+
const gtmContainerId = getGtmContainerPublicId(analyticsConfig);
|
|
153
161
|
const keystoneEnvironment = getKeystoneEnvironment(analyticsConfig);
|
|
154
162
|
|
|
155
163
|
const services = Array.isArray(servicesData) ? servicesData : [];
|
|
@@ -187,6 +195,7 @@ export async function KeystoneRootLayout(props: {
|
|
|
187
195
|
<>
|
|
188
196
|
{metaPixelId ? <MetaPixel pixelId={metaPixelId} /> : null}
|
|
189
197
|
{metaPixelId ? <MetaPixelTracker bookingUrl={externalManagementUrl} /> : null}
|
|
198
|
+
{gtmContainerId ? <GoogleTagManager containerId={gtmContainerId} /> : null}
|
|
190
199
|
<ThemeProvider theme={theme}>
|
|
191
200
|
<KeystoneSSRProvider>
|
|
192
201
|
<FormDefinitionsProvider
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const GTM_SCRIPT = (containerId: string) => `
|
|
2
|
+
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
3
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
4
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
5
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
6
|
+
})(window,document,'script','dataLayer','${containerId.replace(/'/g, "\\'")}');
|
|
7
|
+
`;
|
|
8
|
+
|
|
9
|
+
export type GoogleTagManagerProps = {
|
|
10
|
+
/** GTM container public ID (e.g. GTM-ABC123). */
|
|
11
|
+
containerId: string | null | undefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Renders Google Tag Manager script + noscript fallback.
|
|
16
|
+
* Mount once at root layout level when a container is provisioned.
|
|
17
|
+
*/
|
|
18
|
+
export function GoogleTagManager({ containerId }: GoogleTagManagerProps) {
|
|
19
|
+
const raw = typeof containerId === 'string' ? containerId.trim() : '';
|
|
20
|
+
const id = raw && raw !== 'null' && /^GTM-[A-Z0-9]+$/i.test(raw) ? raw : '';
|
|
21
|
+
|
|
22
|
+
if (!id) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
<script id="google-tag-manager" dangerouslySetInnerHTML={{ __html: GTM_SCRIPT(id) }} />
|
|
29
|
+
<noscript>
|
|
30
|
+
<iframe
|
|
31
|
+
src={`https://www.googletagmanager.com/ns.html?id=${id}`}
|
|
32
|
+
height="0"
|
|
33
|
+
width="0"
|
|
34
|
+
style={{ display: 'none', visibility: 'hidden' }}
|
|
35
|
+
title="google-tag-manager"
|
|
36
|
+
/>
|
|
37
|
+
</noscript>
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
}
|
package/src/tracking/index.ts
CHANGED
|
@@ -26,5 +26,7 @@ export type { PixelEvent, PixelEventParams, PixelUserData } from './firePixelEve
|
|
|
26
26
|
export { PostHogProvider } from './PostHogProvider';
|
|
27
27
|
export type { PostHogProviderProps } from './PostHogProvider';
|
|
28
28
|
export { KeystoneAnalyticsTracker } from './KeystoneAnalyticsTracker';
|
|
29
|
+
export { GoogleTagManager } from './GoogleTagManager';
|
|
30
|
+
export type { GoogleTagManagerProps } from './GoogleTagManager';
|
|
29
31
|
export { captureEvent } from './captureEvent';
|
|
30
32
|
export type { KsEventName, KsEventProperties } from './captureEvent';
|