@jmp-technologies/analytics 0.1.17 → 0.1.18

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 CHANGED
@@ -73,6 +73,8 @@ import {
73
73
 
74
74
  Or call **`trackEmailClick(path)`** / **`trackCallClick(path)`** from `useJmpAnalytics()`.
75
75
 
76
+ For **SMS / WhatsApp / maps / scheduling** link taps, call **`trackContactClick(path, { channel, linkHost })`** — or set **`autoTrackContactLinks: true`** in your config (or **`NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS=true`**) to register one delegated `click` listener that classifies outbound links for you. Auto-tracking is **off by default**; per-link opt-out via `data-jmp-no-track` on the `<a>` (or any ancestor).
77
+
76
78
  **Hooks:** `useJmpAnalytics()` from `@jmp-technologies/analytics/next` or `@jmp-technologies/analytics/react` for forms and custom events.
77
79
 
78
80
  ---
@@ -243,7 +245,7 @@ When present, `category` is an optional section label you can use to group FAQs
243
245
 
244
246
  **Tracking events**
245
247
 
246
- - `trackPageView`, `trackFormSubmit`, `trackCallClick`, `trackEmailClick` (since **0.1.10**), `trackLead`
248
+ - `trackPageView`, `trackFormSubmit`, `trackCallClick`, `trackEmailClick` (since **0.1.10**), `trackContactClick` (since **0.1.18** — SMS, WhatsApp, maps, scheduling), `trackLead`
247
249
 
248
250
  **Content**
249
251
 
@@ -3,7 +3,6 @@ var JMP_SESSION_ID_KEY = "jmp_analytics_sid";
3
3
  var JMP_LANDING_REFERER_KEY = "jmp_analytics_landing_referer";
4
4
  var JMP_LANDING_REFERER_COOKIE = "jmp_lr";
5
5
  var JMP_UTM_SESSION_KEY = "jmp_analytics_utm";
6
- var JMP_EARLY_BEACON_PATH_KEY = "jmp_analytics_early_beacon_path";
7
6
  var LANDING_REFERER_COOKIE_MAX_AGE_SEC = 30 * 60;
8
7
  var JMP_UTM_PARAM_KEYS = [
9
8
  "utm_source",
@@ -136,84 +135,175 @@ function getOrCreateSessionIdFromStorage() {
136
135
  return void 0;
137
136
  }
138
137
  }
139
- function wasEarlyBeaconSentForPath(path) {
140
- if (typeof window === "undefined") {
141
- return false;
138
+ function buildLandingCaptureInlineScript() {
139
+ const cookieMaxAge = String(LANDING_REFERER_COOKIE_MAX_AGE_SEC);
140
+ return `(function(){try{var h=location.hostname;var ref=document.referrer||'';function rh(u){try{return new URL(u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e){try{return new URL('https://'+u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e2){return null}}}function ext(r){var x=rh(r);if(!x)return false;var s=h.replace(/^www\\./i,'').toLowerCase();return x!==s&&x.slice(-('.'+s).length)!==('.'+s)}function apexDom(hn){var s=hn.replace(/^www\\./i,'').toLowerCase();if(!s||s==='localhost'||/\\.local$/i.test(s)||s.indexOf('.')<0)return null;return s}function readCk(hn){var apex=apexDom(hn);if(!apex)return '';var pre='${JMP_LANDING_REFERER_COOKIE}=';var parts=document.cookie.split(';');for(var i=0;i<parts.length;i++){var t=parts[i].trim();if(t.indexOf(pre)===0){try{return decodeURIComponent(t.slice(pre.length)).trim()}catch(e){return ''}}}return ''}function writeCk(r,hn){var apex=apexDom(hn);if(!apex)return;var sec=location.protocol==='https:'?'; Secure':'';document.cookie='${JMP_LANDING_REFERER_COOKIE}='+encodeURIComponent(r.slice(0,2048))+'; Domain=.'+apex+'; Path=/; Max-Age=${cookieMaxAge}; SameSite=Lax'+sec}var stored=sessionStorage.getItem('${JMP_LANDING_REFERER_KEY}')||'';var ck=readCk(h);var preserved=stored||ck;var lr='';if(ref&&ext(ref)){sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',ref);writeCk(ref,h);lr=ref}else{lr=preserved||'';if(lr&&!stored)sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',lr)}var sid=sessionStorage.getItem('${JMP_SESSION_ID_KEY}');if(!sid&&crypto&&crypto.randomUUID){sid=crypto.randomUUID();sessionStorage.setItem('${JMP_SESSION_ID_KEY}',sid)}try{var sp=new URLSearchParams(location.search);var utm={};var updated=false;['utm_source','utm_medium','utm_campaign','utm_content','utm_term'].forEach(function(n){var v=sp.get(n);if(v){utm[n]=v;updated=true}});if(updated)sessionStorage.setItem('${JMP_UTM_SESSION_KEY}',JSON.stringify(utm))}catch(e){}}catch(e){}})();`;
141
+ }
142
+
143
+ // src/contact-link-classifier.ts
144
+ var BOOKING_LINK_HOSTS = [
145
+ "calendly.com",
146
+ "cal.com",
147
+ "acuityscheduling.com",
148
+ "calendar.google.com",
149
+ "calendar.app.google",
150
+ "bookings.microsoft.com",
151
+ "outlook.office.com",
152
+ "outlook.office365.com",
153
+ "book.ms",
154
+ "setmore.com",
155
+ "simplybook.me",
156
+ "oncehub.com",
157
+ "scheduleonce.com",
158
+ "youcanbook.me",
159
+ "savvycal.com",
160
+ "tidycal.com",
161
+ "zohobookings.com",
162
+ "square.site",
163
+ "squareup.com",
164
+ "meetings.hubspot.com",
165
+ "jobber.com",
166
+ "housecallpro.com",
167
+ "servicetitan.com",
168
+ "thryv.com",
169
+ "honeybook.com",
170
+ "dubsado.com",
171
+ "fresha.com",
172
+ "booksy.com",
173
+ "vagaro.com",
174
+ "mindbodyonline.com",
175
+ "mindbody.io",
176
+ "janeapp.com",
177
+ "cliniko.com",
178
+ "practicebetter.io"
179
+ ];
180
+ var WHATSAPP_HOSTS = ["wa.me", "api.whatsapp.com", "whatsapp.com"];
181
+ function hostnameMatches(host, pattern) {
182
+ const h = host.toLowerCase();
183
+ const p = pattern.toLowerCase();
184
+ return h === p || h.endsWith(`.${p}`);
185
+ }
186
+ function isMapsHost(host, pathname) {
187
+ if (hostnameMatches(host, "maps.apple.com")) {
188
+ return true;
142
189
  }
143
- try {
144
- return sessionStorage.getItem(JMP_EARLY_BEACON_PATH_KEY) === path;
145
- } catch {
146
- return false;
190
+ if (hostnameMatches(host, "maps.app.goo.gl")) {
191
+ return true;
192
+ }
193
+ if (hostnameMatches(host, "google.com") || hostnameMatches(host, "google.co")) {
194
+ return pathname === "/maps" || pathname.startsWith("/maps/") || pathname.startsWith("/local");
147
195
  }
196
+ return false;
148
197
  }
149
- function markEarlyBeaconSentForPath(path) {
150
- if (typeof window === "undefined") {
151
- return;
198
+ function isWhatsAppHost(host, pathname) {
199
+ for (const pattern of WHATSAPP_HOSTS) {
200
+ if (!hostnameMatches(host, pattern)) {
201
+ continue;
202
+ }
203
+ if (pattern === "whatsapp.com") {
204
+ return pathname.startsWith("/send");
205
+ }
206
+ return true;
207
+ }
208
+ return false;
209
+ }
210
+ function isBookingHost(host) {
211
+ for (const pattern of BOOKING_LINK_HOSTS) {
212
+ if (hostnameMatches(host, pattern)) {
213
+ return true;
214
+ }
215
+ }
216
+ return false;
217
+ }
218
+ function classifyContactHref(href) {
219
+ const raw = href.trim();
220
+ if (!raw || raw.startsWith("#") || raw.startsWith("javascript:")) {
221
+ return null;
222
+ }
223
+ const lower = raw.toLowerCase();
224
+ if (lower.startsWith("tel:")) {
225
+ return { kind: "call" };
226
+ }
227
+ if (lower.startsWith("mailto:")) {
228
+ return { kind: "email" };
152
229
  }
230
+ if (lower.startsWith("sms:") || lower.startsWith("smsto:")) {
231
+ return { kind: "contact_click", channel: "sms", linkHost: null };
232
+ }
233
+ if (lower.startsWith("geo:")) {
234
+ return { kind: "contact_click", channel: "maps", linkHost: null };
235
+ }
236
+ if (raw.startsWith("/") || raw.startsWith("?")) {
237
+ return null;
238
+ }
239
+ let url;
153
240
  try {
154
- sessionStorage.setItem(JMP_EARLY_BEACON_PATH_KEY, path);
241
+ url = new URL(raw);
155
242
  } catch {
243
+ return null;
244
+ }
245
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
246
+ return null;
247
+ }
248
+ const host = url.hostname.toLowerCase();
249
+ const pathname = url.pathname.toLowerCase();
250
+ if (isWhatsAppHost(host, pathname)) {
251
+ return { kind: "contact_click", channel: "whatsapp", linkHost: host };
252
+ }
253
+ if (isMapsHost(host, pathname)) {
254
+ return { kind: "contact_click", channel: "maps", linkHost: host };
255
+ }
256
+ if (isBookingHost(host)) {
257
+ return { kind: "contact_click", channel: "booking", linkHost: host };
156
258
  }
259
+ return null;
157
260
  }
158
- function sendEarlyPageViewBeacon(args) {
159
- if (typeof window === "undefined" || typeof fetch === "undefined") {
261
+
262
+ // src/index.ts
263
+ var JMP_ANALYTICS_SDK_VERSION = "0.1.18";
264
+ var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
265
+ var moduleTrackingConsentGranted = true;
266
+ var trackingConsentListeners = /* @__PURE__ */ new Set();
267
+ function readStoredTrackingConsent() {
268
+ if (typeof window === "undefined") {
160
269
  return false;
161
270
  }
162
- const path = `${window.location.pathname}${window.location.search}` || "/";
163
- if (wasEarlyBeaconSentForPath(path)) {
271
+ try {
272
+ return localStorage.getItem(JMP_TRACKING_CONSENT_STORAGE_KEY) === "granted";
273
+ } catch {
164
274
  return false;
165
275
  }
166
- const { landingReferer, utm } = captureLandingAttribution(window.location.hostname);
167
- const sessionId = getOrCreateSessionIdFromStorage();
168
- const metadata = {
169
- pageHostname: window.location.hostname,
170
- earlyBeacon: true,
171
- ...utm
172
- };
173
- if (landingReferer) {
174
- metadata.referer = landingReferer;
175
- }
176
- const payload = {
177
- type: "page_view",
178
- path,
179
- trackingKey: args.trackingKey,
180
- ...sessionId ? { sessionId } : {},
181
- metadata
182
- };
183
- const headers = {
184
- "Content-Type": "application/json",
185
- "X-JMP-Tracking-Key": args.trackingKey
276
+ }
277
+ function isJmpTrackingConsentGranted() {
278
+ return moduleTrackingConsentGranted;
279
+ }
280
+ function subscribeJmpTrackingConsent(listener) {
281
+ trackingConsentListeners.add(listener);
282
+ return () => {
283
+ trackingConsentListeners.delete(listener);
186
284
  };
187
- if (landingReferer) {
188
- headers["X-JMP-Visitor-Referer"] = landingReferer;
285
+ }
286
+ function setJmpTrackingConsent(granted) {
287
+ if (moduleTrackingConsentGranted === granted) {
288
+ return;
189
289
  }
190
- markEarlyBeaconSentForPath(path);
191
- void fetch(`${args.baseUrl.replace(/\/$/, "")}/api/events`, {
192
- method: "POST",
193
- headers,
194
- body: JSON.stringify(payload),
195
- keepalive: true,
196
- mode: "cors",
197
- credentials: "omit"
198
- }).catch(() => {
290
+ moduleTrackingConsentGranted = granted;
291
+ if (typeof window !== "undefined") {
199
292
  try {
200
- sessionStorage.removeItem(JMP_EARLY_BEACON_PATH_KEY);
293
+ localStorage.setItem(
294
+ JMP_TRACKING_CONSENT_STORAGE_KEY,
295
+ granted ? "granted" : "denied"
296
+ );
201
297
  } catch {
202
298
  }
203
- });
204
- return true;
205
- }
206
- function escapeInlineScript(value) {
207
- return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
208
- }
209
- function buildLandingCaptureInlineScript(args) {
210
- const baseUrl = escapeInlineScript(args.baseUrl.replace(/\/$/, ""));
211
- const trackingKey = escapeInlineScript(args.trackingKey);
212
- const cookieMaxAge = String(LANDING_REFERER_COOKIE_MAX_AGE_SEC);
213
- return `(function(){try{var k='${trackingKey}',b='${baseUrl}';if(!k||!b)return;var p=location.pathname+location.search||'/';var sentKey='${JMP_EARLY_BEACON_PATH_KEY}';if(sessionStorage.getItem(sentKey)===p)return;var h=location.hostname;var ref=document.referrer||'';function rh(u){try{return new URL(u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e){try{return new URL('https://'+u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e2){return null}}}function ext(r){var x=rh(r);if(!x)return false;var s=h.replace(/^www\\./i,'').toLowerCase();return x!==s&&x.slice(-('.'+s).length)!==('.'+s)}function apexDom(hn){var s=hn.replace(/^www\\./i,'').toLowerCase();if(!s||s==='localhost'||/\\.local$/i.test(s)||s.indexOf('.')<0)return null;return s}function readCk(hn){var apex=apexDom(hn);if(!apex)return '';var pre='${JMP_LANDING_REFERER_COOKIE}=';var parts=document.cookie.split(';');for(var i=0;i<parts.length;i++){var t=parts[i].trim();if(t.indexOf(pre)===0){try{return decodeURIComponent(t.slice(pre.length)).trim()}catch(e){return ''}}}return ''}function writeCk(r,hn){var apex=apexDom(hn);if(!apex)return;var sec=location.protocol==='https:'?'; Secure':'';document.cookie='${JMP_LANDING_REFERER_COOKIE}='+encodeURIComponent(r.slice(0,2048))+'; Domain=.'+apex+'; Path=/; Max-Age=${cookieMaxAge}; SameSite=Lax'+sec}var stored=sessionStorage.getItem('${JMP_LANDING_REFERER_KEY}')||'';var ck=readCk(h);var preserved=stored||ck;var lr='';if(ref&&ext(ref)){sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',ref);writeCk(ref,h);lr=ref}else{lr=preserved||'';if(lr&&!stored)sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',lr)}var sid=sessionStorage.getItem('${JMP_SESSION_ID_KEY}');if(!sid&&crypto&&crypto.randomUUID){sid=crypto.randomUUID();sessionStorage.setItem('${JMP_SESSION_ID_KEY}',sid)}var md={pageHostname:h,earlyBeacon:true};try{var sp=new URLSearchParams(location.search);['utm_source','utm_medium','utm_campaign','utm_content','utm_term'].forEach(function(n){var v=sp.get(n);if(v)md[n]=v})}catch(e){}if(lr)md.referer=lr;var body=JSON.stringify({type:'page_view',path:p,trackingKey:k,sessionId:sid||undefined,metadata:md});var hd={'Content-Type':'application/json','X-JMP-Tracking-Key':k};if(lr)hd['X-JMP-Visitor-Referer']=lr;sessionStorage.setItem(sentKey,p);fetch(b+'/api/events',{method:'POST',headers:hd,body:body,keepalive:true,mode:'cors',credentials:'omit'}).catch(function(){sessionStorage.removeItem(sentKey)})}catch(e){}})();`;
299
+ if (granted) {
300
+ captureLandingAttribution(window.location.hostname);
301
+ }
302
+ }
303
+ for (const listener of trackingConsentListeners) {
304
+ listener();
305
+ }
214
306
  }
215
-
216
- // src/index.ts
217
307
  function captureAndGetLandingReferer() {
218
308
  if (typeof window === "undefined") {
219
309
  return null;
@@ -288,9 +378,16 @@ function createJmpAnalytics(config) {
288
378
  );
289
379
  }
290
380
  const fetchFn = resolvedFetch;
381
+ moduleTrackingConsentGranted = config.requireConsent ? readStoredTrackingConsent() : true;
382
+ function canSend() {
383
+ return moduleTrackingConsentGranted;
384
+ }
291
385
  let lastDedupePath = "";
292
386
  let lastDedupeAt = 0;
293
387
  async function send(body) {
388
+ if (!canSend()) {
389
+ return;
390
+ }
294
391
  const url = `${baseUrl}/api/events`;
295
392
  const headers = {
296
393
  "Content-Type": "application/json",
@@ -346,6 +443,9 @@ function createJmpAnalytics(config) {
346
443
  }
347
444
  }
348
445
  async function sendLead(body) {
446
+ if (!canSend()) {
447
+ return;
448
+ }
349
449
  const url = `${baseUrl}/api/leads`;
350
450
  const headers = {
351
451
  "Content-Type": "application/json",
@@ -408,6 +508,9 @@ function createJmpAnalytics(config) {
408
508
  return false;
409
509
  }
410
510
  function trackPageView(options) {
511
+ if (!canSend()) {
512
+ return Promise.resolve();
513
+ }
411
514
  const pathFromOptions = options?.path?.trim();
412
515
  let pathname = "/";
413
516
  let search = "";
@@ -423,9 +526,6 @@ function createJmpAnalytics(config) {
423
526
  search = window.location.search.replace(/^\?/, "");
424
527
  }
425
528
  const path = search ? `${pathname}?${search}` : pathname;
426
- if (wasEarlyBeaconSentForPath(path)) {
427
- return Promise.resolve();
428
- }
429
529
  if (shouldDedupePageView(pathname)) {
430
530
  return Promise.resolve();
431
531
  }
@@ -476,6 +576,20 @@ function createJmpAnalytics(config) {
476
576
  metadata: metadata ?? {}
477
577
  });
478
578
  }
579
+ function trackContactClick(path, options) {
580
+ const metadata = {
581
+ ...options.metadata && typeof options.metadata === "object" ? options.metadata : {},
582
+ channel: options.channel
583
+ };
584
+ if (options.linkHost) {
585
+ metadata.linkHost = options.linkHost;
586
+ }
587
+ return send({
588
+ type: "contact_click",
589
+ path: path || "/",
590
+ metadata
591
+ });
592
+ }
479
593
  function trackLead(options) {
480
594
  const path = options?.path ?? (typeof window !== "undefined" ? window.location.pathname : "/");
481
595
  const body = { path: path || "/" };
@@ -508,7 +622,20 @@ function createJmpAnalytics(config) {
508
622
  if (type === "call_click") {
509
623
  return trackCallClick(payload.path, payload.metadata);
510
624
  }
511
- return trackEmailClick(payload.path, payload.metadata);
625
+ if (type === "email_click") {
626
+ return trackEmailClick(payload.path, payload.metadata);
627
+ }
628
+ const meta = payload.metadata ?? {};
629
+ const channel = typeof meta.channel === "string" ? meta.channel : "";
630
+ const linkHost = typeof meta.linkHost === "string" ? meta.linkHost : null;
631
+ if (channel !== "sms" && channel !== "whatsapp" && channel !== "maps" && channel !== "booking") {
632
+ return Promise.resolve();
633
+ }
634
+ return trackContactClick(payload.path, {
635
+ channel,
636
+ linkHost,
637
+ metadata: meta
638
+ });
512
639
  }
513
640
  function subscribeToSpaNavigation() {
514
641
  if (typeof window === "undefined") {
@@ -542,12 +669,75 @@ function createJmpAnalytics(config) {
542
669
  history.replaceState = replace;
543
670
  };
544
671
  }
545
- if (typeof window !== "undefined") {
672
+ let lastContactClickKey = "";
673
+ let lastContactClickAt = 0;
674
+ function subscribeContactLinkAutoTrack() {
675
+ if (typeof window === "undefined" || typeof document === "undefined") {
676
+ return () => {
677
+ };
678
+ }
679
+ const handler = (event) => {
680
+ if (!canSend()) {
681
+ return;
682
+ }
683
+ const target = event.target;
684
+ if (!(target instanceof Element)) {
685
+ return;
686
+ }
687
+ const anchor = target.closest("a[href]");
688
+ if (!(anchor instanceof HTMLAnchorElement)) {
689
+ return;
690
+ }
691
+ if (anchor.closest("[data-jmp-no-track]")) {
692
+ return;
693
+ }
694
+ const href = anchor.getAttribute("href") ?? "";
695
+ const classified = classifyContactHref(href);
696
+ if (!classified) {
697
+ return;
698
+ }
699
+ const path = window.location.pathname;
700
+ if (classified.kind === "call") {
701
+ if (dedupeContactClick(`call_click:${path}`)) {
702
+ return;
703
+ }
704
+ void trackCallClick(path);
705
+ return;
706
+ }
707
+ if (classified.kind === "email") {
708
+ if (dedupeContactClick(`email_click:${path}`)) {
709
+ return;
710
+ }
711
+ void trackEmailClick(path);
712
+ return;
713
+ }
714
+ if (dedupeContactClick(`contact_click:${classified.channel}:${path}`)) {
715
+ return;
716
+ }
717
+ void trackContactClick(path, {
718
+ channel: classified.channel,
719
+ linkHost: classified.linkHost
720
+ });
721
+ };
722
+ document.addEventListener("click", handler, { capture: true });
723
+ return () => {
724
+ document.removeEventListener("click", handler, { capture: true });
725
+ };
726
+ }
727
+ function dedupeContactClick(key) {
728
+ const now = Date.now();
729
+ if (key === lastContactClickKey && now - lastContactClickAt < 1e3) {
730
+ return true;
731
+ }
732
+ lastContactClickKey = key;
733
+ lastContactClickAt = now;
734
+ return false;
735
+ }
736
+ if (typeof window !== "undefined" && canSend()) {
546
737
  captureLandingAttribution(window.location.hostname);
547
- sendEarlyPageViewBeacon({
548
- baseUrl,
549
- trackingKey: config.trackingKey
550
- });
738
+ }
739
+ if (typeof window !== "undefined" && config.autoTrackContactLinks && canSend()) {
740
+ subscribeContactLinkAutoTrack();
551
741
  }
552
742
  return {
553
743
  track,
@@ -555,8 +745,12 @@ function createJmpAnalytics(config) {
555
745
  trackFormSubmit,
556
746
  trackCallClick,
557
747
  trackEmailClick,
748
+ trackContactClick,
558
749
  trackLead,
559
- subscribeToSpaNavigation
750
+ subscribeToSpaNavigation,
751
+ subscribeContactLinkAutoTrack,
752
+ setTrackingConsent: setJmpTrackingConsent,
753
+ isTrackingConsentGranted: isJmpTrackingConsentGranted
560
754
  };
561
755
  }
562
756
  async function trackJmpServerPageView(config, options = {}) {
@@ -679,7 +873,10 @@ async function registerJmpContentWrappers(config) {
679
873
  "Content-Type": "application/json",
680
874
  "X-JMP-Tracking-Key": config.trackingKey
681
875
  },
682
- body: JSON.stringify({ wrappers })
876
+ body: JSON.stringify({
877
+ wrappers,
878
+ sdkVersion: JMP_ANALYTICS_SDK_VERSION
879
+ })
683
880
  });
684
881
  const text = await res.text();
685
882
  if (!res.ok) {
@@ -777,11 +974,15 @@ function getJmpBrowserAnalyticsConfigFromEnv(overrides) {
777
974
  const baseUrl = readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_URL");
778
975
  const trackingKey = readProcessEnv("NEXT_PUBLIC_JMP_TRACKING_KEY");
779
976
  if (!baseUrl || !trackingKey) return null;
977
+ const requireConsentFromEnv = readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT") === "true";
978
+ const autoTrackContactLinksFromEnv = readProcessEnv("NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS") === "true";
780
979
  return {
781
980
  baseUrl,
782
981
  trackingKey,
783
982
  pageViewDedupeMs: DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
784
- ...overrides
983
+ ...overrides,
984
+ requireConsent: overrides?.requireConsent ?? requireConsentFromEnv,
985
+ autoTrackContactLinks: overrides?.autoTrackContactLinks ?? autoTrackContactLinksFromEnv
785
986
  };
786
987
  }
787
988
  function getJmpServerContentConfigFromEnv(overrides) {
@@ -814,8 +1015,14 @@ function createJmpContentClientFromServerEnv(overrides) {
814
1015
  }
815
1016
 
816
1017
  export {
817
- sendEarlyPageViewBeacon,
818
1018
  buildLandingCaptureInlineScript,
1019
+ BOOKING_LINK_HOSTS,
1020
+ classifyContactHref,
1021
+ JMP_ANALYTICS_SDK_VERSION,
1022
+ JMP_TRACKING_CONSENT_STORAGE_KEY,
1023
+ isJmpTrackingConsentGranted,
1024
+ subscribeJmpTrackingConsent,
1025
+ setJmpTrackingConsent,
819
1026
  createJmpAnalytics,
820
1027
  trackJmpServerPageView,
821
1028
  getJmpBlogPosts,
@@ -835,4 +1042,4 @@ export {
835
1042
  getOrCreateJmpAnalyticsFromBrowserEnv,
836
1043
  createJmpContentClientFromServerEnv
837
1044
  };
838
- //# sourceMappingURL=chunk-MUHLIN7P.js.map
1045
+ //# sourceMappingURL=chunk-SOHYQ5GT.js.map