@jmp-technologies/analytics 0.1.30 → 0.1.33
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/astro/client.cjs +30 -2
- package/dist/astro/client.cjs.map +1 -1
- package/dist/astro/client.d.cts +2 -2
- package/dist/astro/client.d.ts +2 -2
- package/dist/astro/client.js +1 -1
- package/dist/astro/content.cjs +84 -14
- package/dist/astro/content.cjs.map +1 -1
- package/dist/astro/content.d.cts +10 -8
- package/dist/astro/content.d.ts +10 -8
- package/dist/astro/content.js +6 -2
- package/dist/astro/integration.cjs.map +1 -1
- package/dist/astro/integration.js +2 -2
- package/dist/astro/middleware.d.cts +2 -2
- package/dist/astro/middleware.d.ts +2 -2
- package/dist/astro/register.cjs.map +1 -1
- package/dist/astro/register.js +2 -2
- package/dist/{chunk-ZEC22LFP.js → chunk-4Q6YOXKB.js} +2 -2
- package/dist/{chunk-LLTB7ZFC.js → chunk-AIOUOA24.js} +18 -8
- package/dist/chunk-AIOUOA24.js.map +1 -0
- package/dist/{chunk-FS4BZ7DR.js → chunk-FH5CJNQD.js} +36 -10
- package/dist/chunk-FH5CJNQD.js.map +1 -0
- package/dist/{chunk-YCVHRMM6.js → chunk-G5BMWPQ6.js} +2 -3
- package/dist/{chunk-YCVHRMM6.js.map → chunk-G5BMWPQ6.js.map} +1 -1
- package/dist/{chunk-LTPLLPOR.js → chunk-JMALYARK.js} +2 -2
- package/dist/{chunk-GTPKRBFR.js → chunk-KTPL3R5E.js} +132 -12
- package/dist/chunk-KTPL3R5E.js.map +1 -0
- package/dist/chunk-RI3KKDPX.js +75 -0
- package/dist/chunk-RI3KKDPX.js.map +1 -0
- package/dist/{create-jmp-analytics-BeuuU6as.d.ts → create-jmp-analytics-CwtcXBd7.d.ts} +1 -2
- package/dist/{create-jmp-analytics-Ce2CrhhR.d.cts → create-jmp-analytics-lkGcysG_.d.cts} +1 -2
- package/dist/index.cjs +133 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -12
- package/dist/index.d.ts +24 -12
- package/dist/index.js +9 -1
- package/dist/next/content.cjs +86 -14
- package/dist/next/content.cjs.map +1 -1
- package/dist/next/content.d.cts +6 -4
- package/dist/next/content.d.ts +6 -4
- package/dist/next/content.js +8 -2
- package/dist/next/content.js.map +1 -1
- package/dist/next/instrumentation.cjs.map +1 -1
- package/dist/next/instrumentation.js +1 -1
- package/dist/next/landing-capture-script-server.cjs +1 -2
- package/dist/next/landing-capture-script-server.cjs.map +1 -1
- package/dist/next/landing-capture-script-server.js +1 -1
- package/dist/next/landing-pages.cjs.map +1 -1
- package/dist/next/landing-pages.d.cts +3 -14
- package/dist/next/landing-pages.d.ts +3 -14
- package/dist/next/landing-pages.js +13 -65
- package/dist/next/landing-pages.js.map +1 -1
- package/dist/next/locations.cjs +737 -0
- package/dist/next/locations.cjs.map +1 -0
- package/dist/next/locations.d.cts +55 -0
- package/dist/next/locations.d.ts +55 -0
- package/dist/next/locations.js +158 -0
- package/dist/next/locations.js.map +1 -0
- package/dist/next/middleware.d.cts +2 -2
- package/dist/next/middleware.d.ts +2 -2
- package/dist/next/site-root-server.cjs +31 -4
- package/dist/next/site-root-server.cjs.map +1 -1
- package/dist/next/site-root-server.js +4 -4
- package/dist/next.cjs +44 -8
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +3 -3
- package/dist/next.d.ts +3 -3
- package/dist/next.js +3 -3
- package/dist/react.cjs +163 -127
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{site-config-DIFmnwqv.d.cts → site-config-BMlEQ_8g.d.cts} +1 -1
- package/dist/{site-config-B4uEj4xX.d.ts → site-config-BbE6kGDd.d.ts} +1 -1
- package/dist/{track-page-view-CkgIp9-j.d.ts → track-page-view-BPWGGoMr.d.ts} +1 -1
- package/dist/{track-page-view-Bv0BAvxG.d.cts → track-page-view-DaNOaIxF.d.cts} +1 -1
- package/dist/{types-B2iP79lb.d.cts → types-BdC3SRH-.d.cts} +57 -2
- package/dist/{types-B2iP79lb.d.ts → types-BdC3SRH-.d.ts} +57 -2
- package/dist/utils-B4E-pcQ0.d.ts +15 -0
- package/dist/utils-DIHFgovG.d.cts +15 -0
- package/package.json +7 -2
- package/dist/chunk-FS4BZ7DR.js.map +0 -1
- package/dist/chunk-GTPKRBFR.js.map +0 -1
- package/dist/chunk-LLTB7ZFC.js.map +0 -1
- /package/dist/{chunk-ZEC22LFP.js.map → chunk-4Q6YOXKB.js.map} +0 -0
- /package/dist/{chunk-LTPLLPOR.js.map → chunk-JMALYARK.js.map} +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
extractMailtoTarget,
|
|
3
|
+
extractTelTarget,
|
|
2
4
|
getOrCreateJmpAnalyticsFromBrowserEnv
|
|
3
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KTPL3R5E.js";
|
|
4
6
|
|
|
5
7
|
// src/react.tsx
|
|
6
8
|
import { useMemo } from "react";
|
|
@@ -8,13 +10,21 @@ import { jsx } from "react/jsx-runtime";
|
|
|
8
10
|
function useJmpAnalytics() {
|
|
9
11
|
return useMemo(() => getOrCreateJmpAnalyticsFromBrowserEnv(), []);
|
|
10
12
|
}
|
|
11
|
-
function
|
|
13
|
+
function trackCallClickFromHref(href) {
|
|
12
14
|
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
13
|
-
|
|
15
|
+
const contactTarget = extractTelTarget(href);
|
|
16
|
+
void getOrCreateJmpAnalyticsFromBrowserEnv()?.trackCallClick(
|
|
17
|
+
path,
|
|
18
|
+
contactTarget ? { contactTarget } : void 0
|
|
19
|
+
);
|
|
14
20
|
}
|
|
15
|
-
function
|
|
21
|
+
function trackEmailClickFromHref(href) {
|
|
16
22
|
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
17
|
-
|
|
23
|
+
const contactTarget = extractMailtoTarget(href);
|
|
24
|
+
void getOrCreateJmpAnalyticsFromBrowserEnv()?.trackEmailClick(
|
|
25
|
+
path,
|
|
26
|
+
contactTarget ? { contactTarget } : void 0
|
|
27
|
+
);
|
|
18
28
|
}
|
|
19
29
|
function JmpTrackedTelLink({
|
|
20
30
|
href,
|
|
@@ -28,7 +38,7 @@ function JmpTrackedTelLink({
|
|
|
28
38
|
"data-jmp-tracked": "true",
|
|
29
39
|
...rest,
|
|
30
40
|
onClick: (e) => {
|
|
31
|
-
|
|
41
|
+
trackCallClickFromHref(href);
|
|
32
42
|
onClick?.(e);
|
|
33
43
|
}
|
|
34
44
|
}
|
|
@@ -46,7 +56,7 @@ function JmpTrackedMailtoLink({
|
|
|
46
56
|
"data-jmp-tracked": "true",
|
|
47
57
|
...rest,
|
|
48
58
|
onClick: (e) => {
|
|
49
|
-
|
|
59
|
+
trackEmailClickFromHref(href);
|
|
50
60
|
onClick?.(e);
|
|
51
61
|
}
|
|
52
62
|
}
|
|
@@ -58,4 +68,4 @@ export {
|
|
|
58
68
|
JmpTrackedTelLink,
|
|
59
69
|
JmpTrackedMailtoLink
|
|
60
70
|
};
|
|
61
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-AIOUOA24.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx"],"sourcesContent":["\"use client\"\n\nimport { useMemo, type ComponentPropsWithoutRef } from \"react\"\nimport type { JmpAnalytics } from \"./index\"\nimport { extractMailtoTarget, extractTelTarget } from \"./contact-link-classifier\"\nimport { getOrCreateJmpAnalyticsFromBrowserEnv } from \"./index\"\n\nexport function useJmpAnalytics(): JmpAnalytics | null {\n return useMemo(() => getOrCreateJmpAnalyticsFromBrowserEnv(), [])\n}\n\nfunction trackCallClickFromHref(href: string): void {\n const path =\n typeof window !== \"undefined\" ? window.location.pathname : \"/\"\n const contactTarget = extractTelTarget(href)\n void getOrCreateJmpAnalyticsFromBrowserEnv()?.trackCallClick(\n path,\n contactTarget ? { contactTarget } : undefined\n )\n}\n\nfunction trackEmailClickFromHref(href: string): void {\n const path =\n typeof window !== \"undefined\" ? window.location.pathname : \"/\"\n const contactTarget = extractMailtoTarget(href)\n void getOrCreateJmpAnalyticsFromBrowserEnv()?.trackEmailClick(\n path,\n contactTarget ? { contactTarget } : undefined\n )\n}\n\nexport type JmpTrackedTelLinkProps = ComponentPropsWithoutRef<\"a\"> & {\n href: string\n}\n\n/**\n * `tel:` (or other) link that records a `call_click` with the current path.\n */\nexport function JmpTrackedTelLink({\n href,\n onClick,\n ...rest\n}: JmpTrackedTelLinkProps) {\n return (\n <a\n href={href}\n data-jmp-tracked=\"true\"\n {...rest}\n onClick={(e) => {\n trackCallClickFromHref(href)\n onClick?.(e)\n }}\n />\n )\n}\n\nexport type JmpTrackedMailtoLinkProps = ComponentPropsWithoutRef<\"a\"> & {\n href: string\n}\n\n/**\n * `mailto:` link that records an `email_click` with the current path.\n */\nexport function JmpTrackedMailtoLink({\n href,\n onClick,\n ...rest\n}: JmpTrackedMailtoLinkProps) {\n return (\n <a\n href={href}\n data-jmp-tracked=\"true\"\n {...rest}\n onClick={(e) => {\n trackEmailClickFromHref(href)\n onClick?.(e)\n }}\n />\n )\n}\n"],"mappings":";;;;;;;AAEA,SAAS,eAA8C;AA0CnD;AArCG,SAAS,kBAAuC;AACrD,SAAO,QAAQ,MAAM,sCAAsC,GAAG,CAAC,CAAC;AAClE;AAEA,SAAS,uBAAuB,MAAoB;AAClD,QAAM,OACJ,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAC7D,QAAM,gBAAgB,iBAAiB,IAAI;AAC3C,OAAK,sCAAsC,GAAG;AAAA,IAC5C;AAAA,IACA,gBAAgB,EAAE,cAAc,IAAI;AAAA,EACtC;AACF;AAEA,SAAS,wBAAwB,MAAoB;AACnD,QAAM,OACJ,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAC7D,QAAM,gBAAgB,oBAAoB,IAAI;AAC9C,OAAK,sCAAsC,GAAG;AAAA,IAC5C;AAAA,IACA,gBAAgB,EAAE,cAAc,IAAI;AAAA,EACtC;AACF;AASO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA2B;AACzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,oBAAiB;AAAA,MAChB,GAAG;AAAA,MACJ,SAAS,CAAC,MAAM;AACd,+BAAuB,IAAI;AAC3B,kBAAU,CAAC;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;AASO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA8B;AAC5B,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,oBAAiB;AAAA,MAChB,GAAG;AAAA,MACJ,SAAS,CAAC,MAAM;AACd,gCAAwB,IAAI;AAC5B,kBAAU,CAAC;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
getJmpLandingPageDetail,
|
|
6
6
|
getJmpLandingPageSitemap,
|
|
7
7
|
getJmpLandingPages,
|
|
8
|
+
getJmpLocationDetail,
|
|
9
|
+
getJmpLocations,
|
|
8
10
|
getJmpSiteProfile,
|
|
9
11
|
getJmpTrustBundle
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KTPL3R5E.js";
|
|
11
13
|
import {
|
|
12
14
|
getJmpContentConfig,
|
|
13
15
|
getJmpSiteDefinition
|
|
@@ -114,47 +116,47 @@ function listResolvedSocialUrls(social) {
|
|
|
114
116
|
social.youtube
|
|
115
117
|
].filter((url) => Boolean(url));
|
|
116
118
|
}
|
|
117
|
-
async function loadBlogPosts() {
|
|
119
|
+
async function loadBlogPosts(locale) {
|
|
118
120
|
const c = getJmpContentConfig();
|
|
119
121
|
if (!c) {
|
|
120
122
|
return [];
|
|
121
123
|
}
|
|
122
124
|
try {
|
|
123
|
-
const posts = await getJmpBlogPosts(c);
|
|
125
|
+
const posts = await getJmpBlogPosts(c, locale ? { locale } : void 0);
|
|
124
126
|
return sortBlogPosts(posts);
|
|
125
127
|
} catch {
|
|
126
128
|
return [];
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
|
-
async function loadBlogPost(slug) {
|
|
131
|
+
async function loadBlogPost(slug, locale) {
|
|
130
132
|
const c = getJmpContentConfig();
|
|
131
133
|
if (!c) {
|
|
132
134
|
return null;
|
|
133
135
|
}
|
|
134
136
|
try {
|
|
135
|
-
return await getJmpBlogPost(c, slug);
|
|
137
|
+
return await getJmpBlogPost(c, slug, locale);
|
|
136
138
|
} catch {
|
|
137
139
|
return null;
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
|
-
async function loadFaqs() {
|
|
142
|
+
async function loadFaqs(locale) {
|
|
141
143
|
const c = getJmpContentConfig();
|
|
142
144
|
if (!c) {
|
|
143
145
|
return [];
|
|
144
146
|
}
|
|
145
147
|
try {
|
|
146
|
-
const faqs = await getJmpFaqs(c);
|
|
148
|
+
const faqs = await getJmpFaqs(c, locale ? { locale } : void 0);
|
|
147
149
|
return sortFaqs(faqs);
|
|
148
150
|
} catch {
|
|
149
151
|
return [];
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
|
-
async function loadFaqBySlug(slug) {
|
|
154
|
+
async function loadFaqBySlug(slug, locale) {
|
|
153
155
|
const normalized = slug.trim();
|
|
154
156
|
if (!normalized) {
|
|
155
157
|
return null;
|
|
156
158
|
}
|
|
157
|
-
const items = await loadFaqs();
|
|
159
|
+
const items = await loadFaqs(locale);
|
|
158
160
|
return items.find((item) => item.slug === normalized || item.id === normalized) ?? null;
|
|
159
161
|
}
|
|
160
162
|
async function loadLandingPages(filters) {
|
|
@@ -190,6 +192,28 @@ async function loadLandingPageSitemap() {
|
|
|
190
192
|
return [];
|
|
191
193
|
}
|
|
192
194
|
}
|
|
195
|
+
async function loadLocations() {
|
|
196
|
+
const c = getJmpContentConfig();
|
|
197
|
+
if (!c) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
return await getJmpLocations(c);
|
|
202
|
+
} catch {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async function loadLocationDetail(slug) {
|
|
207
|
+
const c = getJmpContentConfig();
|
|
208
|
+
if (!c) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
return await getJmpLocationDetail(c, slug);
|
|
213
|
+
} catch {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
193
217
|
async function loadTrustBundle() {
|
|
194
218
|
const c = getJmpContentConfig();
|
|
195
219
|
if (!c) {
|
|
@@ -227,7 +251,9 @@ export {
|
|
|
227
251
|
loadLandingPages,
|
|
228
252
|
loadLandingPageDetail,
|
|
229
253
|
loadLandingPageSitemap,
|
|
254
|
+
loadLocations,
|
|
255
|
+
loadLocationDetail,
|
|
230
256
|
loadTrustBundle,
|
|
231
257
|
filterFeaturedTrustQuotes
|
|
232
258
|
};
|
|
233
|
-
//# sourceMappingURL=chunk-
|
|
259
|
+
//# sourceMappingURL=chunk-FH5CJNQD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/content/site-content.ts"],"sourcesContent":["import {\n getJmpBlogPost,\n getJmpBlogPosts,\n getJmpFaqs,\n getJmpLandingPageDetail,\n getJmpLandingPageSitemap,\n getJmpLandingPages,\n getJmpLocations,\n getJmpLocationDetail,\n getJmpSiteProfile,\n getJmpTrustBundle,\n type JmpBlogPost,\n type JmpFaqItem,\n type JmpLandingPage,\n type JmpLandingPageDetail,\n type JmpLandingPageKind,\n type JmpLandingPageSitemapEntry,\n type JmpWebsiteLocation,\n type JmpWebsiteLocationDetail,\n type JmpSiteProfile,\n type JmpTestimonial,\n type JmpTrustBundle,\n} from \"../index\"\nimport {\n getJmpContentConfig,\n getJmpSiteDefinition,\n type JmpSiteSocialLinks,\n} from \"../site-config\"\n\nexport type {\n JmpBlogPost,\n JmpFaqItem,\n JmpLandingPage,\n JmpLandingPageDetail,\n JmpLandingPageKind,\n JmpLandingPageSitemapEntry,\n JmpWebsiteLocation,\n JmpWebsiteLocationDetail,\n JmpSiteProfile,\n JmpTestimonial,\n JmpTrustBundle,\n}\n\nexport { getJmpContentConfig } from \"../site-config\"\n\nexport type { JmpSiteSocialLinks } from \"../site-config\"\n\nexport type ResolvedSiteContact = {\n displayName: string\n email: string\n founderName: string\n dashboardDemoUrl: string\n profilePhotoSrc: string\n linkedin: string | null\n social: JmpSiteSocialLinks\n phone: string | null\n address: string | null\n googleMapsUrl: string | null\n googleMapsEmbedUrl: string | null\n hours: string | null\n serviceArea: string | null\n privacyUrl: string\n termsUrl: string\n cta: { label: string | null; url: string | null }\n}\n\nconst DEFAULT_EXTRA_KEYS = {\n founderName: [\"founder-name\", \"founder_name\"],\n dashboardDemoUrl: [\"dashboard-demo-url\", \"sample-dashboard-url\"],\n profilePhotoSrc: [\"profile-photo-url\", \"profile_photo_url\"],\n hours: [\"hours\", \"business-hours\"],\n serviceArea: [\"service-area\", \"service_area\", \"service-area-text\"],\n googleMapsEmbedUrl: [\"google-maps-embed-url\", \"google_maps_embed_url\"],\n} as const\n\nfunction sortBlogPosts(posts: JmpBlogPost[]): JmpBlogPost[] {\n return [...posts].sort((a, b) => {\n const da = a.published_at ?? a.updated_at\n const db = b.published_at ?? b.updated_at\n return db.localeCompare(da)\n })\n}\n\nfunction sortFaqs(items: JmpFaqItem[]): JmpFaqItem[] {\n return [...items].sort((a, b) => a.sort_order - b.sort_order)\n}\n\nfunction readProfileExtra(\n profile: JmpSiteProfile | null,\n keys: readonly string[],\n): string | null {\n for (const key of keys) {\n const value = profile?.extras?.[key]?.trim()\n if (value) {\n return value\n }\n }\n return null\n}\n\n/** Resolve a path or URL against {@link defineJmpSite}'s `siteUrl`. */\nexport function absoluteSiteAssetUrl(src: string): string {\n const trimmed = src.trim()\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed\n }\n const siteUrl = getJmpSiteDefinition()?.siteUrl?.replace(/\\/$/, \"\")\n if (!siteUrl) {\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`\n }\n return `${siteUrl}${trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`}`\n}\n\nexport async function loadSiteProfile(): Promise<JmpSiteProfile | null> {\n const config = getJmpContentConfig()\n if (!config) {\n return null\n }\n try {\n return await getJmpSiteProfile(config)\n } catch {\n return null\n }\n}\n\nexport function resolveSiteContact(profile: JmpSiteProfile | null): ResolvedSiteContact {\n const site = getJmpSiteDefinition()\n const fallback = site?.contactFallback ?? {}\n const extraKeys = {\n ...DEFAULT_EXTRA_KEYS,\n ...site?.contactExtraKeys,\n }\n\n const email = profile?.email?.trim() || fallback.email || \"\"\n const social: JmpSiteSocialLinks = {\n linkedin:\n profile?.social?.linkedin?.trim() || fallback.linkedin || null,\n instagram:\n profile?.social?.instagram?.trim() || fallback.instagram || null,\n facebook:\n profile?.social?.facebook?.trim() || fallback.facebook || null,\n x: profile?.social?.x?.trim() || fallback.x || null,\n youtube:\n profile?.social?.youtube?.trim() || fallback.youtube || null,\n }\n const phone = profile?.phone?.trim() || fallback.phone || null\n\n return {\n displayName:\n profile?.display_name?.trim() ||\n profile?.name?.trim() ||\n fallback.displayName ||\n \"\",\n founderName:\n readProfileExtra(profile, extraKeys.founderName ?? []) ||\n fallback.founderName ||\n \"\",\n dashboardDemoUrl:\n readProfileExtra(profile, extraKeys.dashboardDemoUrl ?? []) ||\n fallback.dashboardDemoUrl ||\n \"\",\n profilePhotoSrc:\n readProfileExtra(profile, extraKeys.profilePhotoSrc ?? []) ||\n fallback.profilePhotoSrc ||\n \"\",\n email,\n linkedin: social.linkedin,\n social,\n phone,\n address: profile?.address?.trim() || fallback.address || null,\n googleMapsUrl:\n profile?.google_maps_url?.trim() || fallback.googleMapsUrl || null,\n googleMapsEmbedUrl:\n readProfileExtra(profile, extraKeys.googleMapsEmbedUrl ?? []) ||\n fallback.googleMapsEmbedUrl ||\n null,\n hours:\n readProfileExtra(profile, extraKeys.hours ?? []) || fallback.hours || null,\n serviceArea:\n readProfileExtra(profile, extraKeys.serviceArea ?? []) ||\n fallback.serviceArea ||\n null,\n privacyUrl: profile?.legal?.privacy_policy_url?.trim() || fallback.privacyUrl || \"/privacy\",\n termsUrl: profile?.legal?.terms_url?.trim() || fallback.termsUrl || \"/terms\",\n cta: {\n label: profile?.cta?.label?.trim() || null,\n url: profile?.cta?.url?.trim() || null,\n },\n }\n}\n\nexport async function getResolvedSiteContact(): Promise<ResolvedSiteContact> {\n const profile = await loadSiteProfile()\n return resolveSiteContact(profile)\n}\n\n/** Non-null social profile URLs in a stable order for JSON-LD `sameAs`. */\nexport function listResolvedSocialUrls(social: JmpSiteSocialLinks): string[] {\n return [\n social.linkedin,\n social.instagram,\n social.facebook,\n social.x,\n social.youtube,\n ].filter((url): url is string => Boolean(url))\n}\n\nexport async function loadBlogPosts(locale?: string): Promise<JmpBlogPost[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n const posts = await getJmpBlogPosts(c, locale ? { locale } : undefined)\n return sortBlogPosts(posts)\n } catch {\n return []\n }\n}\n\nexport async function loadBlogPost(\n slug: string,\n locale?: string\n): Promise<JmpBlogPost | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpBlogPost(c, slug, locale)\n } catch {\n return null\n }\n}\n\nexport async function loadFaqs(locale?: string): Promise<JmpFaqItem[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n const faqs = await getJmpFaqs(c, locale ? { locale } : undefined)\n return sortFaqs(faqs)\n } catch {\n return []\n }\n}\n\nexport async function loadFaqBySlug(\n slug: string,\n locale?: string\n): Promise<JmpFaqItem | null> {\n const normalized = slug.trim()\n if (!normalized) {\n return null\n }\n const items = await loadFaqs(locale)\n return (\n items.find((item) => item.slug === normalized || item.id === normalized) ?? null\n )\n}\n\nexport async function loadLandingPages(filters?: {\n kind?: JmpLandingPageKind\n locale?: string\n}): Promise<JmpLandingPage[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n return await getJmpLandingPages(c, filters)\n } catch {\n return []\n }\n}\n\nexport async function loadLandingPageDetail(\n kind: JmpLandingPageKind,\n slug: string,\n locale?: string\n): Promise<JmpLandingPageDetail | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpLandingPageDetail(c, kind, slug, locale)\n } catch {\n return null\n }\n}\n\nexport async function loadLandingPageSitemap(): Promise<JmpLandingPageSitemapEntry[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n return await getJmpLandingPageSitemap(c)\n } catch {\n return []\n }\n}\n\nexport async function loadLocations(): Promise<JmpWebsiteLocation[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n return await getJmpLocations(c)\n } catch {\n return []\n }\n}\n\nexport async function loadLocationDetail(\n slug: string\n): Promise<JmpWebsiteLocationDetail | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpLocationDetail(c, slug)\n } catch {\n return null\n }\n}\n\nexport async function loadTrustBundle(): Promise<JmpTrustBundle | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpTrustBundle(c)\n } catch {\n return null\n }\n}\n\nexport function filterFeaturedTrustQuotes(\n testimonials: JmpTestimonial[],\n placement: \"testimonials\" | \"reviews\",\n limit = 2,\n): JmpTestimonial[] {\n return testimonials\n .filter((item) => {\n if (!item.featured) {\n return false\n }\n const bucket = item.placement?.trim().toLowerCase()\n if (placement === \"reviews\") {\n return bucket === \"reviews\"\n }\n return !bucket || bucket === \"testimonials\"\n })\n .sort((a, b) => a.sort_order - b.sort_order)\n .slice(0, limit)\n}\n"],"mappings":"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","names":[]}
|
|
@@ -16,8 +16,7 @@ function JmpLandingCaptureScriptServer({
|
|
|
16
16
|
dangerouslySetInnerHTML: {
|
|
17
17
|
__html: buildLandingCaptureInlineScript()
|
|
18
18
|
},
|
|
19
|
-
id: "jmp-landing-capture"
|
|
20
|
-
suppressHydrationWarning: true
|
|
19
|
+
id: "jmp-landing-capture"
|
|
21
20
|
}
|
|
22
21
|
);
|
|
23
22
|
}
|
|
@@ -25,4 +24,4 @@ function JmpLandingCaptureScriptServer({
|
|
|
25
24
|
export {
|
|
26
25
|
JmpLandingCaptureScriptServer
|
|
27
26
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-G5BMWPQ6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/next/landing-capture-script-server.tsx"],"sourcesContent":["import { buildLandingCaptureInlineScript } from \"../landing-capture\"\n\ntype JmpLandingCaptureScriptServerProps = {\n trackingKey?: string\n}\n\n/**\n * SSR-only landing referrer / UTM capture. Render in root layout `<head>`.\n *\n * Do not use `next/script` or a client component — React 19 will warn and\n * deferred client mounts miss the first referrer anyway.\n */\nexport function JmpLandingCaptureScriptServer({\n trackingKey,\n}: JmpLandingCaptureScriptServerProps = {}) {\n if (!trackingKey?.trim()) {\n return null\n }\n\n return (\n <script\n dangerouslySetInnerHTML={{\n __html: buildLandingCaptureInlineScript(),\n }}\n id=\"jmp-landing-capture\"\n
|
|
1
|
+
{"version":3,"sources":["../src/next/landing-capture-script-server.tsx"],"sourcesContent":["import { buildLandingCaptureInlineScript } from \"../landing-capture\"\n\ntype JmpLandingCaptureScriptServerProps = {\n trackingKey?: string\n}\n\n/**\n * SSR-only landing referrer / UTM capture. Render in root layout `<head>`.\n *\n * Do not use `next/script` or a client component — React 19 will warn and\n * deferred client mounts miss the first referrer anyway.\n */\nexport function JmpLandingCaptureScriptServer({\n trackingKey,\n}: JmpLandingCaptureScriptServerProps = {}) {\n if (!trackingKey?.trim()) {\n return null\n }\n\n return (\n <script\n dangerouslySetInnerHTML={{\n __html: buildLandingCaptureInlineScript(),\n }}\n id=\"jmp-landing-capture\"\n />\n )\n}\n"],"mappings":";;;;;AAoBI;AARG,SAAS,8BAA8B;AAAA,EAC5C;AACF,IAAwC,CAAC,GAAG;AAC1C,MAAI,CAAC,aAAa,KAAK,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,yBAAyB;AAAA,QACvB,QAAQ,gCAAgC;AAAA,MAC1C;AAAA,MACA,IAAG;AAAA;AAAA,EACL;AAEJ;","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
getOrCreateJmpAnalyticsFromBrowserEnv,
|
|
3
3
|
isJmpTrackingConsentGranted,
|
|
4
4
|
subscribeJmpTrackingConsent
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KTPL3R5E.js";
|
|
6
6
|
import {
|
|
7
7
|
readJmpPublicEnvFromProcess
|
|
8
8
|
} from "./chunk-AIFJ7DVO.js";
|
|
@@ -130,4 +130,4 @@ export {
|
|
|
130
130
|
JmpNextAnalytics,
|
|
131
131
|
JmpSiteRoot
|
|
132
132
|
};
|
|
133
|
-
//# sourceMappingURL=chunk-
|
|
133
|
+
//# sourceMappingURL=chunk-JMALYARK.js.map
|
|
@@ -130,6 +130,26 @@ function classifyContactHref(href) {
|
|
|
130
130
|
}
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
133
|
+
function extractTelTarget(href) {
|
|
134
|
+
const raw = href.trim();
|
|
135
|
+
if (!raw.toLowerCase().startsWith("tel:")) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const target = decodeURIComponent(
|
|
139
|
+
raw.slice(4).split("?")[0]?.split(";")[0] ?? ""
|
|
140
|
+
).trim();
|
|
141
|
+
return target || null;
|
|
142
|
+
}
|
|
143
|
+
function extractMailtoTarget(href) {
|
|
144
|
+
const raw = href.trim();
|
|
145
|
+
if (!raw.toLowerCase().startsWith("mailto:")) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const target = decodeURIComponent(
|
|
149
|
+
raw.slice(7).split("?")[0]?.split(",")[0] ?? ""
|
|
150
|
+
).trim();
|
|
151
|
+
return target || null;
|
|
152
|
+
}
|
|
133
153
|
|
|
134
154
|
// src/constants.ts
|
|
135
155
|
var JMP_ANALYTICS_SDK_VERSION = "0.1.26";
|
|
@@ -517,14 +537,22 @@ function createJmpAnalytics(config) {
|
|
|
517
537
|
if (dedupeContactClick(`call_click:${path}`)) {
|
|
518
538
|
return;
|
|
519
539
|
}
|
|
520
|
-
|
|
540
|
+
const contactTarget = extractTelTarget(href);
|
|
541
|
+
void trackCallClick(
|
|
542
|
+
path,
|
|
543
|
+
contactTarget ? { contactTarget } : void 0
|
|
544
|
+
);
|
|
521
545
|
return;
|
|
522
546
|
}
|
|
523
547
|
if (classified.kind === "email") {
|
|
524
548
|
if (dedupeContactClick(`email_click:${path}`)) {
|
|
525
549
|
return;
|
|
526
550
|
}
|
|
527
|
-
|
|
551
|
+
const contactTarget = extractMailtoTarget(href);
|
|
552
|
+
void trackEmailClick(
|
|
553
|
+
path,
|
|
554
|
+
contactTarget ? { contactTarget } : void 0
|
|
555
|
+
);
|
|
528
556
|
return;
|
|
529
557
|
}
|
|
530
558
|
if (dedupeContactClick(`contact_click:${classified.channel}:${path}`)) {
|
|
@@ -959,20 +987,30 @@ function sortWrapperSlots(slots) {
|
|
|
959
987
|
function afterContentWrapperUse(config) {
|
|
960
988
|
scheduleContentWrapperSync(config);
|
|
961
989
|
}
|
|
962
|
-
async function getJmpBlogPosts(config) {
|
|
990
|
+
async function getJmpBlogPosts(config, filters) {
|
|
991
|
+
const params = new URLSearchParams();
|
|
992
|
+
if (filters?.locale) {
|
|
993
|
+
params.set("locale", filters.locale);
|
|
994
|
+
}
|
|
995
|
+
const query = params.toString();
|
|
963
996
|
const data = await getContent(
|
|
964
997
|
config,
|
|
965
|
-
|
|
998
|
+
`/api/content/blog${query ? `?${query}` : ""}`
|
|
966
999
|
);
|
|
967
1000
|
markContentWrapper("blog");
|
|
968
1001
|
afterContentWrapperUse(config);
|
|
969
1002
|
return data.posts;
|
|
970
1003
|
}
|
|
971
|
-
async function getJmpBlogPost(config, slug) {
|
|
1004
|
+
async function getJmpBlogPost(config, slug, locale) {
|
|
972
1005
|
try {
|
|
1006
|
+
const params = new URLSearchParams();
|
|
1007
|
+
if (locale) {
|
|
1008
|
+
params.set("locale", locale);
|
|
1009
|
+
}
|
|
1010
|
+
const query = params.toString();
|
|
973
1011
|
const data = await getContent(
|
|
974
1012
|
config,
|
|
975
|
-
`/api/content/blog/${encodeURIComponent(slug)}`
|
|
1013
|
+
`/api/content/blog/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`
|
|
976
1014
|
);
|
|
977
1015
|
markContentWrapper("blog");
|
|
978
1016
|
afterContentWrapperUse(config);
|
|
@@ -984,15 +1022,62 @@ async function getJmpBlogPost(config, slug) {
|
|
|
984
1022
|
throw error;
|
|
985
1023
|
}
|
|
986
1024
|
}
|
|
987
|
-
async function
|
|
1025
|
+
async function getJmpBlogPostDetail(config, slug, locale) {
|
|
1026
|
+
try {
|
|
1027
|
+
const params = new URLSearchParams();
|
|
1028
|
+
if (locale) {
|
|
1029
|
+
params.set("locale", locale);
|
|
1030
|
+
}
|
|
1031
|
+
const query = params.toString();
|
|
1032
|
+
const data = await getContent(
|
|
1033
|
+
config,
|
|
1034
|
+
`/api/content/blog/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`
|
|
1035
|
+
);
|
|
1036
|
+
markContentWrapper("blog");
|
|
1037
|
+
afterContentWrapperUse(config);
|
|
1038
|
+
return data;
|
|
1039
|
+
} catch (error) {
|
|
1040
|
+
if (error instanceof Error && error.message.includes("HTTP 404")) {
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
throw error;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
async function getJmpFaqs(config, filters) {
|
|
1047
|
+
const params = new URLSearchParams();
|
|
1048
|
+
if (filters?.locale) {
|
|
1049
|
+
params.set("locale", filters.locale);
|
|
1050
|
+
}
|
|
1051
|
+
const query = params.toString();
|
|
988
1052
|
const data = await getContent(
|
|
989
1053
|
config,
|
|
990
|
-
|
|
1054
|
+
`/api/content/faqs${query ? `?${query}` : ""}`
|
|
991
1055
|
);
|
|
992
1056
|
markContentWrapper("faq");
|
|
993
1057
|
afterContentWrapperUse(config);
|
|
994
1058
|
return data.faqs;
|
|
995
1059
|
}
|
|
1060
|
+
async function getJmpFaqDetail(config, slug, locale) {
|
|
1061
|
+
try {
|
|
1062
|
+
const params = new URLSearchParams();
|
|
1063
|
+
if (locale) {
|
|
1064
|
+
params.set("locale", locale);
|
|
1065
|
+
}
|
|
1066
|
+
const query = params.toString();
|
|
1067
|
+
const data = await getContent(
|
|
1068
|
+
config,
|
|
1069
|
+
`/api/content/faqs/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`
|
|
1070
|
+
);
|
|
1071
|
+
markContentWrapper("faq");
|
|
1072
|
+
afterContentWrapperUse(config);
|
|
1073
|
+
return data;
|
|
1074
|
+
} catch (error) {
|
|
1075
|
+
if (error instanceof Error && error.message.includes("HTTP 404")) {
|
|
1076
|
+
return null;
|
|
1077
|
+
}
|
|
1078
|
+
throw error;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
996
1081
|
async function getJmpLandingPages(config, filters) {
|
|
997
1082
|
const params = new URLSearchParams();
|
|
998
1083
|
if (filters?.kind) {
|
|
@@ -1040,6 +1125,35 @@ async function getJmpLandingPageSitemap(config) {
|
|
|
1040
1125
|
afterContentWrapperUse(config);
|
|
1041
1126
|
return data.entries;
|
|
1042
1127
|
}
|
|
1128
|
+
async function getJmpLocations(config) {
|
|
1129
|
+
const data = await getContent(
|
|
1130
|
+
config,
|
|
1131
|
+
"/api/content/locations"
|
|
1132
|
+
);
|
|
1133
|
+
markContentWrapper("locations");
|
|
1134
|
+
afterContentWrapperUse(config);
|
|
1135
|
+
return data.locations;
|
|
1136
|
+
}
|
|
1137
|
+
async function getJmpLocationDetail(config, slug) {
|
|
1138
|
+
const normalized = slug.trim();
|
|
1139
|
+
if (!normalized) {
|
|
1140
|
+
return null;
|
|
1141
|
+
}
|
|
1142
|
+
try {
|
|
1143
|
+
const detail = await getContent(
|
|
1144
|
+
config,
|
|
1145
|
+
`/api/content/locations/${encodeURIComponent(normalized)}`
|
|
1146
|
+
);
|
|
1147
|
+
markContentWrapper("locations");
|
|
1148
|
+
afterContentWrapperUse(config);
|
|
1149
|
+
return detail;
|
|
1150
|
+
} catch (error) {
|
|
1151
|
+
if (error instanceof Error && error.message.includes("HTTP 404")) {
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1154
|
+
throw error;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1043
1157
|
async function getJmpTrustBundle(config) {
|
|
1044
1158
|
const bundle = await getContent(config, "/api/content/trust");
|
|
1045
1159
|
markTrustBundleWrappers(bundle);
|
|
@@ -1118,9 +1232,9 @@ setContentWrapperSyncHandler(registerJmpContentWrappers);
|
|
|
1118
1232
|
// src/content/client.ts
|
|
1119
1233
|
function createJmpContentClient(config) {
|
|
1120
1234
|
return {
|
|
1121
|
-
getBlogPosts: () => getJmpBlogPosts(config),
|
|
1122
|
-
getBlogPost: (slug) => getJmpBlogPost(config, slug),
|
|
1123
|
-
getFaqs: () => getJmpFaqs(config),
|
|
1235
|
+
getBlogPosts: (filters) => getJmpBlogPosts(config, filters),
|
|
1236
|
+
getBlogPost: (slug, locale) => getJmpBlogPost(config, slug, locale),
|
|
1237
|
+
getFaqs: (filters) => getJmpFaqs(config, filters),
|
|
1124
1238
|
getLandingPages: (filters) => getJmpLandingPages(config, filters),
|
|
1125
1239
|
getLandingPageDetail: (kind, slug, locale) => getJmpLandingPageDetail(config, kind, slug, locale),
|
|
1126
1240
|
getLandingPageSitemap: () => getJmpLandingPageSitemap(config),
|
|
@@ -1179,6 +1293,8 @@ function createJmpContentClientFromServerEnv(overrides) {
|
|
|
1179
1293
|
export {
|
|
1180
1294
|
BOOKING_LINK_HOSTS,
|
|
1181
1295
|
classifyContactHref,
|
|
1296
|
+
extractTelTarget,
|
|
1297
|
+
extractMailtoTarget,
|
|
1182
1298
|
JMP_ANALYTICS_SDK_VERSION,
|
|
1183
1299
|
JMP_TRACKING_CONSENT_STORAGE_KEY,
|
|
1184
1300
|
DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
@@ -1194,10 +1310,14 @@ export {
|
|
|
1194
1310
|
resetContentWrapperDiscoveryForTests,
|
|
1195
1311
|
getJmpBlogPosts,
|
|
1196
1312
|
getJmpBlogPost,
|
|
1313
|
+
getJmpBlogPostDetail,
|
|
1197
1314
|
getJmpFaqs,
|
|
1315
|
+
getJmpFaqDetail,
|
|
1198
1316
|
getJmpLandingPages,
|
|
1199
1317
|
getJmpLandingPageDetail,
|
|
1200
1318
|
getJmpLandingPageSitemap,
|
|
1319
|
+
getJmpLocations,
|
|
1320
|
+
getJmpLocationDetail,
|
|
1201
1321
|
getJmpTrustBundle,
|
|
1202
1322
|
getJmpSiteProfile,
|
|
1203
1323
|
getJmpRobotsTxt,
|
|
@@ -1210,4 +1330,4 @@ export {
|
|
|
1210
1330
|
getOrCreateJmpAnalyticsFromBrowserEnv,
|
|
1211
1331
|
createJmpContentClientFromServerEnv
|
|
1212
1332
|
};
|
|
1213
|
-
//# sourceMappingURL=chunk-
|
|
1333
|
+
//# sourceMappingURL=chunk-KTPL3R5E.js.map
|