@jmp-technologies/analytics 0.1.12 → 0.1.16
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/dist/{chunk-ST5BERIA.js → chunk-AEQGPTDY.js} +219 -52
- package/dist/chunk-AEQGPTDY.js.map +1 -0
- package/dist/{chunk-ZLWI2UAP.js → chunk-P4IKTSPX.js} +2 -2
- package/dist/index.cjs +221 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +5 -1
- package/dist/next.cjs +259 -53
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +12 -5
- package/dist/next.d.ts +12 -5
- package/dist/next.js +36 -6
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +207 -51
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-ST5BERIA.js.map +0 -1
- /package/dist/{chunk-ZLWI2UAP.js.map → chunk-P4IKTSPX.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
type EarlyPageViewBeaconArgs = {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
trackingKey: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Capture landing referrer/UTMs and send an early page_view (fetch keepalive).
|
|
7
|
+
* Safe to call from inline script or module init.
|
|
8
|
+
*/
|
|
9
|
+
declare function sendEarlyPageViewBeacon(args: EarlyPageViewBeaconArgs): boolean;
|
|
10
|
+
/** Inline script for Next.js `beforeInteractive` — earliest capture + beacon. */
|
|
11
|
+
declare function buildLandingCaptureInlineScript(args: {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
trackingKey: string;
|
|
14
|
+
}): string;
|
|
15
|
+
|
|
1
16
|
type JmpEventType = "page_view" | "form_submit" | "call_click" | "email_click";
|
|
2
17
|
type JmpAnalyticsConfig = {
|
|
3
18
|
/** Dashboard origin, e.g. https://analytics.example.com (no trailing slash) */
|
|
@@ -306,4 +321,4 @@ type JmpContentClient = ReturnType<typeof createJmpContentClient>;
|
|
|
306
321
|
*/
|
|
307
322
|
declare function createJmpContentClientFromServerEnv(overrides?: Partial<JmpContentConfig>): JmpContentClient | null;
|
|
308
323
|
|
|
309
|
-
export { DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, type JmpAnalytics, type JmpAnalyticsConfig, type JmpBlogPost, type JmpContentClient, type JmpContentConfig, type JmpContentWrapper, type JmpCredential, type JmpEventType, type JmpFaqItem, type JmpPartnerLogo, type JmpServerRequestLike, type JmpSiteProfile, type JmpTestimonial, type JmpTrustBundle, type JmpTrustSlot, type JmpTrustStat, type JmpTrustSummary, type LeadMetadata, type LeadMetadataValue, type TrackLeadOptions, type TrackPageViewOptions, type TrackServerPageViewOptions, createJmpAnalytics, createJmpContentClient, createJmpContentClientFromServerEnv, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, registerJmpContentWrappers, registerJmpTrustCapabilities, trackJmpServerPageView };
|
|
324
|
+
export { DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, type JmpAnalytics, type JmpAnalyticsConfig, type JmpBlogPost, type JmpContentClient, type JmpContentConfig, type JmpContentWrapper, type JmpCredential, type JmpEventType, type JmpFaqItem, type JmpPartnerLogo, type JmpServerRequestLike, type JmpSiteProfile, type JmpTestimonial, type JmpTrustBundle, type JmpTrustSlot, type JmpTrustStat, type JmpTrustSummary, type LeadMetadata, type LeadMetadataValue, type TrackLeadOptions, type TrackPageViewOptions, type TrackServerPageViewOptions, buildLandingCaptureInlineScript, createJmpAnalytics, createJmpContentClient, createJmpContentClientFromServerEnv, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, registerJmpContentWrappers, registerJmpTrustCapabilities, sendEarlyPageViewBeacon, trackJmpServerPageView };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
type EarlyPageViewBeaconArgs = {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
trackingKey: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Capture landing referrer/UTMs and send an early page_view (fetch keepalive).
|
|
7
|
+
* Safe to call from inline script or module init.
|
|
8
|
+
*/
|
|
9
|
+
declare function sendEarlyPageViewBeacon(args: EarlyPageViewBeaconArgs): boolean;
|
|
10
|
+
/** Inline script for Next.js `beforeInteractive` — earliest capture + beacon. */
|
|
11
|
+
declare function buildLandingCaptureInlineScript(args: {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
trackingKey: string;
|
|
14
|
+
}): string;
|
|
15
|
+
|
|
1
16
|
type JmpEventType = "page_view" | "form_submit" | "call_click" | "email_click";
|
|
2
17
|
type JmpAnalyticsConfig = {
|
|
3
18
|
/** Dashboard origin, e.g. https://analytics.example.com (no trailing slash) */
|
|
@@ -306,4 +321,4 @@ type JmpContentClient = ReturnType<typeof createJmpContentClient>;
|
|
|
306
321
|
*/
|
|
307
322
|
declare function createJmpContentClientFromServerEnv(overrides?: Partial<JmpContentConfig>): JmpContentClient | null;
|
|
308
323
|
|
|
309
|
-
export { DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, type JmpAnalytics, type JmpAnalyticsConfig, type JmpBlogPost, type JmpContentClient, type JmpContentConfig, type JmpContentWrapper, type JmpCredential, type JmpEventType, type JmpFaqItem, type JmpPartnerLogo, type JmpServerRequestLike, type JmpSiteProfile, type JmpTestimonial, type JmpTrustBundle, type JmpTrustSlot, type JmpTrustStat, type JmpTrustSummary, type LeadMetadata, type LeadMetadataValue, type TrackLeadOptions, type TrackPageViewOptions, type TrackServerPageViewOptions, createJmpAnalytics, createJmpContentClient, createJmpContentClientFromServerEnv, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, registerJmpContentWrappers, registerJmpTrustCapabilities, trackJmpServerPageView };
|
|
324
|
+
export { DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, type JmpAnalytics, type JmpAnalyticsConfig, type JmpBlogPost, type JmpContentClient, type JmpContentConfig, type JmpContentWrapper, type JmpCredential, type JmpEventType, type JmpFaqItem, type JmpPartnerLogo, type JmpServerRequestLike, type JmpSiteProfile, type JmpTestimonial, type JmpTrustBundle, type JmpTrustSlot, type JmpTrustStat, type JmpTrustSummary, type LeadMetadata, type LeadMetadataValue, type TrackLeadOptions, type TrackPageViewOptions, type TrackServerPageViewOptions, buildLandingCaptureInlineScript, createJmpAnalytics, createJmpContentClient, createJmpContentClientFromServerEnv, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, registerJmpContentWrappers, registerJmpTrustCapabilities, sendEarlyPageViewBeacon, trackJmpServerPageView };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
3
|
+
buildLandingCaptureInlineScript,
|
|
3
4
|
createJmpAnalytics,
|
|
4
5
|
createJmpContentClient,
|
|
5
6
|
createJmpContentClientFromServerEnv,
|
|
@@ -16,10 +17,12 @@ import {
|
|
|
16
17
|
isJmpServerContentEnvConfigured,
|
|
17
18
|
registerJmpContentWrappers,
|
|
18
19
|
registerJmpTrustCapabilities,
|
|
20
|
+
sendEarlyPageViewBeacon,
|
|
19
21
|
trackJmpServerPageView
|
|
20
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-AEQGPTDY.js";
|
|
21
23
|
export {
|
|
22
24
|
DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
25
|
+
buildLandingCaptureInlineScript,
|
|
23
26
|
createJmpAnalytics,
|
|
24
27
|
createJmpContentClient,
|
|
25
28
|
createJmpContentClientFromServerEnv,
|
|
@@ -36,6 +39,7 @@ export {
|
|
|
36
39
|
isJmpServerContentEnvConfigured,
|
|
37
40
|
registerJmpContentWrappers,
|
|
38
41
|
registerJmpTrustCapabilities,
|
|
42
|
+
sendEarlyPageViewBeacon,
|
|
39
43
|
trackJmpServerPageView
|
|
40
44
|
};
|
|
41
45
|
//# sourceMappingURL=index.js.map
|
package/dist/next.cjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,85 +18,267 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/next.tsx
|
|
22
32
|
var next_exports = {};
|
|
23
33
|
__export(next_exports, {
|
|
34
|
+
JmpLandingCaptureScript: () => JmpLandingCaptureScript,
|
|
24
35
|
JmpNextAnalytics: () => JmpNextAnalytics,
|
|
25
36
|
JmpNextPageViewTracker: () => JmpNextPageViewTracker,
|
|
26
37
|
JmpTrackedMailtoLink: () => JmpTrackedMailtoLink,
|
|
27
38
|
JmpTrackedTelLink: () => JmpTrackedTelLink,
|
|
39
|
+
buildLandingCaptureInlineScript: () => buildLandingCaptureInlineScript,
|
|
28
40
|
useJmpAnalytics: () => useJmpAnalytics
|
|
29
41
|
});
|
|
30
42
|
module.exports = __toCommonJS(next_exports);
|
|
43
|
+
var import_script = __toESM(require("next/script"), 1);
|
|
31
44
|
var import_react2 = require("react");
|
|
32
45
|
var import_navigation = require("next/navigation");
|
|
33
46
|
|
|
34
|
-
// src/
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
47
|
+
// src/landing-capture.ts
|
|
48
|
+
var JMP_SESSION_ID_KEY = "jmp_analytics_sid";
|
|
49
|
+
var JMP_LANDING_REFERER_KEY = "jmp_analytics_landing_referer";
|
|
50
|
+
var JMP_LANDING_REFERER_COOKIE = "jmp_lr";
|
|
51
|
+
var JMP_UTM_SESSION_KEY = "jmp_analytics_utm";
|
|
52
|
+
var JMP_EARLY_BEACON_PATH_KEY = "jmp_analytics_early_beacon_path";
|
|
53
|
+
var LANDING_REFERER_COOKIE_MAX_AGE_SEC = 30 * 60;
|
|
54
|
+
var JMP_UTM_PARAM_KEYS = [
|
|
40
55
|
"utm_source",
|
|
41
56
|
"utm_medium",
|
|
42
57
|
"utm_campaign",
|
|
43
58
|
"utm_content",
|
|
44
59
|
"utm_term"
|
|
45
60
|
];
|
|
46
|
-
function
|
|
47
|
-
|
|
61
|
+
function refererHostFromUrl(referer) {
|
|
62
|
+
const trimmed = referer.trim();
|
|
63
|
+
try {
|
|
64
|
+
return new URL(trimmed).hostname.replace(/^www\./i, "").toLowerCase();
|
|
65
|
+
} catch {
|
|
66
|
+
try {
|
|
67
|
+
return new URL(`https://${trimmed}`).hostname.replace(/^www\./i, "").toLowerCase();
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isExternalReferrerUrl(referer, siteHostname) {
|
|
74
|
+
const refHost = refererHostFromUrl(referer);
|
|
75
|
+
if (!refHost) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const site = siteHostname.replace(/^www\./i, "").toLowerCase();
|
|
79
|
+
return refHost !== site && !refHost.endsWith(`.${site}`);
|
|
80
|
+
}
|
|
81
|
+
function registrableSiteDomain(siteHostname) {
|
|
82
|
+
const site = siteHostname.replace(/^www\./i, "").toLowerCase();
|
|
83
|
+
if (!site || site === "localhost" || site.endsWith(".local")) {
|
|
48
84
|
return null;
|
|
49
85
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
86
|
+
if (!site.includes(".")) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return site;
|
|
90
|
+
}
|
|
91
|
+
function readLandingRefererCookie(siteHostname) {
|
|
92
|
+
if (typeof document === "undefined") {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const apex = registrableSiteDomain(siteHostname);
|
|
96
|
+
if (!apex) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const prefix = `${JMP_LANDING_REFERER_COOKIE}=`;
|
|
100
|
+
for (const part of document.cookie.split(";")) {
|
|
101
|
+
const trimmed = part.trim();
|
|
102
|
+
if (!trimmed.startsWith(prefix)) {
|
|
103
|
+
continue;
|
|
54
104
|
}
|
|
55
|
-
|
|
56
|
-
|
|
105
|
+
try {
|
|
106
|
+
const value = decodeURIComponent(trimmed.slice(prefix.length)).trim();
|
|
107
|
+
return value.length > 0 ? value : null;
|
|
108
|
+
} catch {
|
|
57
109
|
return null;
|
|
58
110
|
}
|
|
59
|
-
sessionStorage.setItem(LANDING_REFERRER_STORAGE_KEY, current);
|
|
60
|
-
return current;
|
|
61
|
-
} catch {
|
|
62
|
-
return document.referrer?.trim() || null;
|
|
63
111
|
}
|
|
112
|
+
return null;
|
|
64
113
|
}
|
|
65
|
-
function
|
|
66
|
-
if (typeof
|
|
114
|
+
function writeLandingRefererCookie(referer, siteHostname) {
|
|
115
|
+
if (typeof document === "undefined") {
|
|
67
116
|
return;
|
|
68
117
|
}
|
|
118
|
+
const apex = registrableSiteDomain(siteHostname);
|
|
119
|
+
if (!apex) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const value = encodeURIComponent(referer.trim().slice(0, 2048));
|
|
123
|
+
const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
|
|
124
|
+
document.cookie = `${JMP_LANDING_REFERER_COOKIE}=${value}; Domain=.${apex}; Path=/; Max-Age=${LANDING_REFERER_COOKIE_MAX_AGE_SEC}; SameSite=Lax${secure}`;
|
|
125
|
+
}
|
|
126
|
+
function captureLandingAttribution(siteHostname) {
|
|
127
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
128
|
+
return { landingReferer: null, utm: {} };
|
|
129
|
+
}
|
|
130
|
+
let landingReferer = null;
|
|
131
|
+
let utm = {};
|
|
69
132
|
try {
|
|
133
|
+
const storedReferer = sessionStorage.getItem(JMP_LANDING_REFERER_KEY)?.trim() || null;
|
|
134
|
+
const cookieReferer = readLandingRefererCookie(siteHostname);
|
|
135
|
+
const preservedReferer = storedReferer || cookieReferer;
|
|
136
|
+
const currentReferer = document.referrer?.trim() || null;
|
|
137
|
+
if (currentReferer && isExternalReferrerUrl(currentReferer, siteHostname)) {
|
|
138
|
+
if (!storedReferer) {
|
|
139
|
+
sessionStorage.setItem(JMP_LANDING_REFERER_KEY, currentReferer);
|
|
140
|
+
}
|
|
141
|
+
writeLandingRefererCookie(currentReferer, siteHostname);
|
|
142
|
+
landingReferer = preservedReferer || currentReferer;
|
|
143
|
+
} else if (preservedReferer) {
|
|
144
|
+
landingReferer = preservedReferer;
|
|
145
|
+
if (!storedReferer) {
|
|
146
|
+
sessionStorage.setItem(JMP_LANDING_REFERER_KEY, preservedReferer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
70
149
|
const params = new URLSearchParams(window.location.search);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const parsed = JSON.parse(raw);
|
|
150
|
+
const rawUtm = sessionStorage.getItem(JMP_UTM_SESSION_KEY);
|
|
151
|
+
if (rawUtm) {
|
|
152
|
+
const parsed = JSON.parse(rawUtm);
|
|
75
153
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
76
|
-
|
|
154
|
+
utm = parsed;
|
|
77
155
|
}
|
|
78
156
|
}
|
|
79
157
|
let updated = false;
|
|
80
|
-
for (const key of
|
|
158
|
+
for (const key of JMP_UTM_PARAM_KEYS) {
|
|
81
159
|
const value = params.get(key)?.trim();
|
|
82
160
|
if (value) {
|
|
83
|
-
|
|
161
|
+
utm[key] = value;
|
|
84
162
|
updated = true;
|
|
85
163
|
}
|
|
86
164
|
}
|
|
87
165
|
if (updated) {
|
|
88
|
-
sessionStorage.setItem(
|
|
166
|
+
sessionStorage.setItem(JMP_UTM_SESSION_KEY, JSON.stringify(utm));
|
|
89
167
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
return { landingReferer, utm };
|
|
171
|
+
}
|
|
172
|
+
function getOrCreateSessionIdFromStorage() {
|
|
173
|
+
if (typeof window === "undefined" || !globalThis.crypto?.randomUUID) {
|
|
174
|
+
return void 0;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
let id = sessionStorage.getItem(JMP_SESSION_ID_KEY);
|
|
178
|
+
if (!id) {
|
|
179
|
+
id = crypto.randomUUID();
|
|
180
|
+
sessionStorage.setItem(JMP_SESSION_ID_KEY, id);
|
|
94
181
|
}
|
|
182
|
+
return id;
|
|
183
|
+
} catch {
|
|
184
|
+
return void 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function wasEarlyBeaconSentForPath(path) {
|
|
188
|
+
if (typeof window === "undefined") {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
return sessionStorage.getItem(JMP_EARLY_BEACON_PATH_KEY) === path;
|
|
193
|
+
} catch {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function markEarlyBeaconSentForPath(path) {
|
|
198
|
+
if (typeof window === "undefined") {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
sessionStorage.setItem(JMP_EARLY_BEACON_PATH_KEY, path);
|
|
95
203
|
} catch {
|
|
96
204
|
}
|
|
97
205
|
}
|
|
206
|
+
function sendEarlyPageViewBeacon(args) {
|
|
207
|
+
if (typeof window === "undefined" || typeof fetch === "undefined") {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
const path = `${window.location.pathname}${window.location.search}` || "/";
|
|
211
|
+
if (wasEarlyBeaconSentForPath(path)) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
const { landingReferer, utm } = captureLandingAttribution(window.location.hostname);
|
|
215
|
+
const sessionId = getOrCreateSessionIdFromStorage();
|
|
216
|
+
const metadata = {
|
|
217
|
+
pageHostname: window.location.hostname,
|
|
218
|
+
earlyBeacon: true,
|
|
219
|
+
...utm
|
|
220
|
+
};
|
|
221
|
+
if (landingReferer) {
|
|
222
|
+
metadata.referer = landingReferer;
|
|
223
|
+
}
|
|
224
|
+
const payload = {
|
|
225
|
+
type: "page_view",
|
|
226
|
+
path,
|
|
227
|
+
trackingKey: args.trackingKey,
|
|
228
|
+
...sessionId ? { sessionId } : {},
|
|
229
|
+
metadata
|
|
230
|
+
};
|
|
231
|
+
const headers = {
|
|
232
|
+
"Content-Type": "application/json",
|
|
233
|
+
"X-JMP-Tracking-Key": args.trackingKey
|
|
234
|
+
};
|
|
235
|
+
if (landingReferer) {
|
|
236
|
+
headers["X-JMP-Visitor-Referer"] = landingReferer;
|
|
237
|
+
}
|
|
238
|
+
markEarlyBeaconSentForPath(path);
|
|
239
|
+
void fetch(`${args.baseUrl.replace(/\/$/, "")}/api/events`, {
|
|
240
|
+
method: "POST",
|
|
241
|
+
headers,
|
|
242
|
+
body: JSON.stringify(payload),
|
|
243
|
+
keepalive: true,
|
|
244
|
+
mode: "cors",
|
|
245
|
+
credentials: "omit"
|
|
246
|
+
}).catch(() => {
|
|
247
|
+
try {
|
|
248
|
+
sessionStorage.removeItem(JMP_EARLY_BEACON_PATH_KEY);
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
function escapeInlineScript(value) {
|
|
255
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
256
|
+
}
|
|
257
|
+
function buildLandingCaptureInlineScript(args) {
|
|
258
|
+
const baseUrl = escapeInlineScript(args.baseUrl.replace(/\/$/, ""));
|
|
259
|
+
const trackingKey = escapeInlineScript(args.trackingKey);
|
|
260
|
+
const cookieMaxAge = String(LANDING_REFERER_COOKIE_MAX_AGE_SEC);
|
|
261
|
+
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)){if(!stored)sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',ref);writeCk(ref,h);lr=preserved||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){}})();`;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/index.ts
|
|
265
|
+
function captureAndGetLandingReferer() {
|
|
266
|
+
if (typeof window === "undefined") {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
return captureLandingAttribution(window.location.hostname).landingReferer;
|
|
270
|
+
}
|
|
271
|
+
function mergeSessionUtms(metadata) {
|
|
272
|
+
if (typeof window === "undefined") {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const { utm } = captureLandingAttribution(window.location.hostname);
|
|
276
|
+
for (const key of JMP_UTM_PARAM_KEYS) {
|
|
277
|
+
if (metadata[key] === void 0 && utm[key]) {
|
|
278
|
+
metadata[key] = utm[key];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
98
282
|
function splitPathAndSearch(pathInput) {
|
|
99
283
|
const qIndex = pathInput.indexOf("?");
|
|
100
284
|
if (qIndex === -1) {
|
|
@@ -118,21 +302,6 @@ function inferDevice() {
|
|
|
118
302
|
}
|
|
119
303
|
return window.innerWidth < 768 ? "mobile" : "desktop";
|
|
120
304
|
}
|
|
121
|
-
function getOrCreateSessionId() {
|
|
122
|
-
if (typeof window === "undefined" || !globalThis.crypto?.randomUUID) {
|
|
123
|
-
return void 0;
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
let id = sessionStorage.getItem(SESSION_STORAGE_KEY);
|
|
127
|
-
if (!id) {
|
|
128
|
-
id = crypto.randomUUID();
|
|
129
|
-
sessionStorage.setItem(SESSION_STORAGE_KEY, id);
|
|
130
|
-
}
|
|
131
|
-
return id;
|
|
132
|
-
} catch {
|
|
133
|
-
return void 0;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
305
|
function createJmpAnalytics(config) {
|
|
137
306
|
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
138
307
|
const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
@@ -156,7 +325,7 @@ function createJmpAnalytics(config) {
|
|
|
156
325
|
headers["X-JMP-Visitor-Referer"] = landingReferer;
|
|
157
326
|
}
|
|
158
327
|
}
|
|
159
|
-
const sid =
|
|
328
|
+
const sid = getOrCreateSessionIdFromStorage();
|
|
160
329
|
const payload = { ...body, ...sid ? { sessionId: sid } : {} };
|
|
161
330
|
if (config.debug) {
|
|
162
331
|
console.debug("[@jmp-technologies/analytics]", "POST", url, payload);
|
|
@@ -205,7 +374,7 @@ function createJmpAnalytics(config) {
|
|
|
205
374
|
"Content-Type": "application/json",
|
|
206
375
|
"X-JMP-Tracking-Key": config.trackingKey
|
|
207
376
|
};
|
|
208
|
-
const sid =
|
|
377
|
+
const sid = getOrCreateSessionIdFromStorage();
|
|
209
378
|
const payload = { ...body, ...sid ? { sessionId: sid } : {} };
|
|
210
379
|
if (config.debug) {
|
|
211
380
|
console.debug("[@jmp-technologies/analytics]", "POST", url, payload);
|
|
@@ -277,6 +446,9 @@ function createJmpAnalytics(config) {
|
|
|
277
446
|
search = window.location.search.replace(/^\?/, "");
|
|
278
447
|
}
|
|
279
448
|
const path = search ? `${pathname}?${search}` : pathname;
|
|
449
|
+
if (wasEarlyBeaconSentForPath(path)) {
|
|
450
|
+
return Promise.resolve();
|
|
451
|
+
}
|
|
280
452
|
if (shouldDedupePageView(pathname)) {
|
|
281
453
|
return Promise.resolve();
|
|
282
454
|
}
|
|
@@ -286,7 +458,7 @@ function createJmpAnalytics(config) {
|
|
|
286
458
|
const params = new URLSearchParams(
|
|
287
459
|
search ? `?${search}` : window.location.search
|
|
288
460
|
);
|
|
289
|
-
for (const key of
|
|
461
|
+
for (const key of JMP_UTM_PARAM_KEYS) {
|
|
290
462
|
const v = params.get(key);
|
|
291
463
|
if (v && metadata[key] === void 0) {
|
|
292
464
|
metadata[key] = v;
|
|
@@ -301,7 +473,6 @@ function createJmpAnalytics(config) {
|
|
|
301
473
|
return send({
|
|
302
474
|
type: "page_view",
|
|
303
475
|
path: path || "/",
|
|
304
|
-
source: options?.source ?? DEFAULT_SOURCE,
|
|
305
476
|
device: options?.device ?? inferDevice(),
|
|
306
477
|
country: options?.country,
|
|
307
478
|
metadata
|
|
@@ -394,6 +565,13 @@ function createJmpAnalytics(config) {
|
|
|
394
565
|
history.replaceState = replace;
|
|
395
566
|
};
|
|
396
567
|
}
|
|
568
|
+
if (typeof window !== "undefined") {
|
|
569
|
+
captureLandingAttribution(window.location.hostname);
|
|
570
|
+
sendEarlyPageViewBeacon({
|
|
571
|
+
baseUrl,
|
|
572
|
+
trackingKey: config.trackingKey
|
|
573
|
+
});
|
|
574
|
+
}
|
|
397
575
|
return {
|
|
398
576
|
track,
|
|
399
577
|
trackPageView,
|
|
@@ -478,12 +656,35 @@ function JmpTrackedMailtoLink({
|
|
|
478
656
|
|
|
479
657
|
// src/next.tsx
|
|
480
658
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
659
|
+
function JmpLandingCaptureScript({
|
|
660
|
+
baseUrl = process.env.NEXT_PUBLIC_JMP_ANALYTICS_URL,
|
|
661
|
+
trackingKey = process.env.NEXT_PUBLIC_JMP_TRACKING_KEY
|
|
662
|
+
} = {}) {
|
|
663
|
+
const resolvedBase = baseUrl?.trim();
|
|
664
|
+
const resolvedKey = trackingKey?.trim();
|
|
665
|
+
if (!resolvedBase || !resolvedKey) {
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
669
|
+
import_script.default,
|
|
670
|
+
{
|
|
671
|
+
id: "jmp-landing-capture",
|
|
672
|
+
strategy: "beforeInteractive",
|
|
673
|
+
dangerouslySetInnerHTML: {
|
|
674
|
+
__html: buildLandingCaptureInlineScript({
|
|
675
|
+
baseUrl: resolvedBase,
|
|
676
|
+
trackingKey: resolvedKey
|
|
677
|
+
})
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
);
|
|
681
|
+
}
|
|
481
682
|
function JmpNextPageViewTrackerInner() {
|
|
482
683
|
const pathname = (0, import_navigation.usePathname)();
|
|
483
684
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
484
685
|
const query = searchParams?.toString() ?? "";
|
|
485
686
|
const path = query ? `${pathname}?${query}` : pathname;
|
|
486
|
-
(0, import_react2.
|
|
687
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
487
688
|
const client = getOrCreateJmpAnalyticsFromBrowserEnv();
|
|
488
689
|
void client?.trackPageView({ path });
|
|
489
690
|
}, [path]);
|
|
@@ -493,14 +694,19 @@ function JmpNextPageViewTracker() {
|
|
|
493
694
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JmpNextPageViewTrackerInner, {}) });
|
|
494
695
|
}
|
|
495
696
|
function JmpNextAnalytics() {
|
|
496
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JmpLandingCaptureScript, {}),
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JmpNextPageViewTracker, {})
|
|
700
|
+
] });
|
|
497
701
|
}
|
|
498
702
|
// Annotate the CommonJS export names for ESM import in node:
|
|
499
703
|
0 && (module.exports = {
|
|
704
|
+
JmpLandingCaptureScript,
|
|
500
705
|
JmpNextAnalytics,
|
|
501
706
|
JmpNextPageViewTracker,
|
|
502
707
|
JmpTrackedMailtoLink,
|
|
503
708
|
JmpTrackedTelLink,
|
|
709
|
+
buildLandingCaptureInlineScript,
|
|
504
710
|
useJmpAnalytics
|
|
505
711
|
});
|
|
506
712
|
//# sourceMappingURL=next.cjs.map
|