@shware/analytics 8.5.0 → 8.7.0

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.
Files changed (66) hide show
  1. package/README.md +13 -16
  2. package/dist/hooks/use-uet-id-sync.cjs +19 -0
  3. package/dist/hooks/use-uet-id-sync.cjs.map +1 -0
  4. package/dist/hooks/use-uet-id-sync.d.cts +10 -0
  5. package/dist/hooks/use-uet-id-sync.d.cts.map +1 -0
  6. package/dist/hooks/use-uet-id-sync.d.mts +10 -0
  7. package/dist/hooks/use-uet-id-sync.d.mts.map +1 -0
  8. package/dist/hooks/use-uet-id-sync.mjs +18 -0
  9. package/dist/hooks/use-uet-id-sync.mjs.map +1 -0
  10. package/dist/next/index.cjs +3 -1
  11. package/dist/next/index.cjs.map +1 -1
  12. package/dist/next/index.d.cts +3 -1
  13. package/dist/next/index.d.cts.map +1 -1
  14. package/dist/next/index.d.mts +3 -1
  15. package/dist/next/index.d.mts.map +1 -1
  16. package/dist/next/index.mjs +3 -1
  17. package/dist/next/index.mjs.map +1 -1
  18. package/dist/react-router/index.cjs +3 -1
  19. package/dist/react-router/index.cjs.map +1 -1
  20. package/dist/react-router/index.d.cts +3 -1
  21. package/dist/react-router/index.d.cts.map +1 -1
  22. package/dist/react-router/index.d.mts +3 -1
  23. package/dist/react-router/index.d.mts.map +1 -1
  24. package/dist/react-router/index.mjs +3 -1
  25. package/dist/react-router/index.mjs.map +1 -1
  26. package/dist/server/linkedin-conversions-api.cjs +28 -6
  27. package/dist/server/linkedin-conversions-api.cjs.map +1 -1
  28. package/dist/server/linkedin-conversions-api.d.cts +13 -3
  29. package/dist/server/linkedin-conversions-api.d.cts.map +1 -1
  30. package/dist/server/linkedin-conversions-api.d.mts +13 -3
  31. package/dist/server/linkedin-conversions-api.d.mts.map +1 -1
  32. package/dist/server/linkedin-conversions-api.mjs +28 -6
  33. package/dist/server/linkedin-conversions-api.mjs.map +1 -1
  34. package/dist/server/microsoft-conversions-api.cjs +1 -1
  35. package/dist/server/microsoft-conversions-api.mjs +1 -1
  36. package/dist/server/openai-conversions-api.cjs +1 -1
  37. package/dist/server/openai-conversions-api.mjs +1 -1
  38. package/dist/server/reddit-conversions-api.cjs +1 -1
  39. package/dist/server/reddit-conversions-api.mjs +1 -1
  40. package/dist/tanstack/analytics.cjs +3 -1
  41. package/dist/tanstack/analytics.cjs.map +1 -1
  42. package/dist/tanstack/analytics.d.cts +3 -1
  43. package/dist/tanstack/analytics.d.cts.map +1 -1
  44. package/dist/tanstack/analytics.d.mts +3 -1
  45. package/dist/tanstack/analytics.d.mts.map +1 -1
  46. package/dist/tanstack/analytics.mjs +3 -1
  47. package/dist/tanstack/analytics.mjs.map +1 -1
  48. package/dist/third-parties/index.cjs +3 -1
  49. package/dist/third-parties/index.d.cts +2 -2
  50. package/dist/third-parties/index.d.mts +2 -2
  51. package/dist/third-parties/index.mjs +2 -2
  52. package/dist/third-parties/meta-pixel.cjs +1 -1
  53. package/dist/third-parties/meta-pixel.mjs +1 -1
  54. package/dist/third-parties/microsoft-uet.cjs +45 -17
  55. package/dist/third-parties/microsoft-uet.cjs.map +1 -1
  56. package/dist/third-parties/microsoft-uet.d.cts +13 -19
  57. package/dist/third-parties/microsoft-uet.d.cts.map +1 -1
  58. package/dist/third-parties/microsoft-uet.d.mts +13 -19
  59. package/dist/third-parties/microsoft-uet.d.mts.map +1 -1
  60. package/dist/third-parties/microsoft-uet.mjs +44 -18
  61. package/dist/third-parties/microsoft-uet.mjs.map +1 -1
  62. package/dist/third-parties/openai-pixel.cjs +1 -1
  63. package/dist/third-parties/openai-pixel.mjs +1 -1
  64. package/dist/third-parties/reddit-pixel.cjs +1 -1
  65. package/dist/third-parties/reddit-pixel.mjs +1 -1
  66. package/package.json +1 -1
package/README.md CHANGED
@@ -139,33 +139,30 @@ Microsoft recommends the UET tag and the Conversions API (CAPI) together. The tw
139
139
  (`tagId`, `eventName`, `eventId`): the browser sends the internal event name as the UET action with
140
140
  the event id as `event_id`, the server sends the same name as `eventName` with the same id.
141
141
 
142
- Browser — pass the tag id to the framework `Analytics` component (`<Analytics uetTagId="97267979" />`
143
- from `@shware/analytics/tanstack`, `/next` or `/react-router`), which inlines Microsoft's snippet
144
- with `enableAutoSpaTracking: true`: the tag owns page loads, `sendUETEvent` drops `page_view` and
145
- forwards everything else. Then:
142
+ Browser — pass the tag id and the customer id to the framework `Analytics` component
143
+ (`<Analytics uetTagId="97267979" uetCustomerId="255004870" />` from `@shware/analytics/tanstack`,
144
+ `/next` or `/react-router`). It inlines Microsoft's snippet with `enableAutoSpaTracking: true` (the
145
+ tag owns page loads, `sendUETEvent` drops `page_view` and forwards everything else) and fires the
146
+ Conversions API's ID Sync pixel once per visit for the SDK visitor — anonymous visitors included,
147
+ they are who remarketing audiences are built from. Then:
146
148
 
147
149
  ```ts
148
- import {
149
- sendUETEvent,
150
- setUETUser,
151
- setUETConsent,
152
- sendUETIdSync,
153
- } from '@shware/analytics/third-parties';
150
+ import { sendUETEvent, setUETUser, setUETConsent } from '@shware/analytics/third-parties';
154
151
 
155
152
  setupAnalytics({
156
153
  thirdPartyTrackers: [sendUETEvent],
157
154
  // Enhanced conversions: the tag hashes the email/phone itself before they leave the page.
158
- thirdPartyUserSetters: [setUETUser()],
155
+ thirdPartyUserSetters: [setUETUser],
159
156
  });
160
157
  // Consent mode (EEA/UK/CH): push `default` before the tag loads, `update` on the visitor's choice.
161
158
  setUETConsent('default', { ad_storage: 'denied', wait_for_update: 2000 });
162
- // ID Sync, once per session: ties the visitor id CAPI sends as `anonymousId` to Microsoft's ids.
163
- // Required for remarketing built from CAPI events, recommended for measurement. `VID` must equal
164
- // `anonymousId` and `UID` must equal `externalId`: pass the SDK visitor id and the raw user id —
165
- // the pixel hashes the user id with the same SHA-256 the server sender uses.
166
- sendUETIdSync({ customerId: 255004870, visitorId: (await getVisitor()).id, userId: user.id });
167
159
  ```
168
160
 
161
+ ID Sync ties the visitor id CAPI receives as `anonymousId` to Microsoft's ids — required for
162
+ remarketing built from CAPI events, recommended for measurement. `setUETUser` re-syncs on sign-in
163
+ with the user id hashed into `UID` (the same SHA-256 the server sends as `externalId`). Outside the
164
+ `Analytics` components, `configureUET({ customerId })` + `syncUETVisitor()` do the same.
165
+
169
166
  Server — the token comes from the UET tag's "Use Conversions API" step (or the Campaign Management
170
167
  API's `UetTagAuthKey/Query`; an account whose tag setup lacks that option has to ask Microsoft
171
168
  Advertising support), `tagId` is the UET tag id:
@@ -0,0 +1,19 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_third_parties_microsoft_uet = require("../third-parties/microsoft-uet.cjs");
3
+ let react = require("react");
4
+ //#region src/hooks/use-uet-id-sync.ts
5
+ /**
6
+ * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer
7
+ * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,
8
+ * which is where Microsoft wants it. No-op without a customer id.
9
+ */
10
+ function useUETIdSync(customerId) {
11
+ (0, react.useEffect)(() => {
12
+ require_third_parties_microsoft_uet.configureUET({ customerId });
13
+ if (customerId !== void 0) require_third_parties_microsoft_uet.syncUETVisitor();
14
+ }, [customerId]);
15
+ }
16
+ //#endregion
17
+ exports.useUETIdSync = useUETIdSync;
18
+
19
+ //# sourceMappingURL=use-uet-id-sync.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-uet-id-sync.cjs","names":["syncUETVisitor"],"sources":["../../src/hooks/use-uet-id-sync.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { configureUET, syncUETVisitor } from '../third-parties/microsoft-uet';\n\n/**\n * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer\n * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,\n * which is where Microsoft wants it. No-op without a customer id.\n */\nexport function useUETIdSync(customerId: string | number | undefined) {\n useEffect(() => {\n configureUET({ customerId });\n if (customerId !== undefined) void syncUETVisitor();\n }, [customerId]);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,aAAa,YAAyC;CACpE,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,oCAAA,aAAa,EAAE,WAAW,CAAC;EAC3B,IAAI,eAAe,KAAA,GAAW,oCAAKA,eAAe;CACpD,GAAG,CAAC,UAAU,CAAC;AACjB"}
@@ -0,0 +1,10 @@
1
+ //#region src/hooks/use-uet-id-sync.d.ts
2
+ /**
3
+ * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer
4
+ * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,
5
+ * which is where Microsoft wants it. No-op without a customer id.
6
+ */
7
+ declare function useUETIdSync(customerId: string | number | undefined): void;
8
+ //#endregion
9
+ export { useUETIdSync };
10
+ //# sourceMappingURL=use-uet-id-sync.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-uet-id-sync.d.cts","names":[],"sources":["../../src/hooks/use-uet-id-sync.ts"],"mappings":";;;;;;iBAQgB,aAAa"}
@@ -0,0 +1,10 @@
1
+ //#region src/hooks/use-uet-id-sync.d.ts
2
+ /**
3
+ * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer
4
+ * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,
5
+ * which is where Microsoft wants it. No-op without a customer id.
6
+ */
7
+ declare function useUETIdSync(customerId: string | number | undefined): void;
8
+ //#endregion
9
+ export { useUETIdSync };
10
+ //# sourceMappingURL=use-uet-id-sync.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-uet-id-sync.d.mts","names":[],"sources":["../../src/hooks/use-uet-id-sync.ts"],"mappings":";;;;;;iBAQgB,aAAa"}
@@ -0,0 +1,18 @@
1
+ import { configureUET, syncUETVisitor } from "../third-parties/microsoft-uet.mjs";
2
+ import { useEffect } from "react";
3
+ //#region src/hooks/use-uet-id-sync.ts
4
+ /**
5
+ * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer
6
+ * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,
7
+ * which is where Microsoft wants it. No-op without a customer id.
8
+ */
9
+ function useUETIdSync(customerId) {
10
+ useEffect(() => {
11
+ configureUET({ customerId });
12
+ if (customerId !== void 0) syncUETVisitor();
13
+ }, [customerId]);
14
+ }
15
+ //#endregion
16
+ export { useUETIdSync };
17
+
18
+ //# sourceMappingURL=use-uet-id-sync.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-uet-id-sync.mjs","names":[],"sources":["../../src/hooks/use-uet-id-sync.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { configureUET, syncUETVisitor } from '../third-parties/microsoft-uet';\n\n/**\n * Microsoft Advertising ID Sync from the framework `Analytics` components: record the customer\n * id for `setUETUser` and sync the visitor once per mount — the first page view of the visit,\n * which is where Microsoft wants it. No-op without a customer id.\n */\nexport function useUETIdSync(customerId: string | number | undefined) {\n useEffect(() => {\n configureUET({ customerId });\n if (customerId !== undefined) void syncUETVisitor();\n }, [customerId]);\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,aAAa,YAAyC;CACpE,gBAAgB;EACd,aAAa,EAAE,WAAW,CAAC;EAC3B,IAAI,eAAe,KAAA,GAAW,eAAoB;CACpD,GAAG,CAAC,UAAU,CAAC;AACjB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
4
4
  const require_track_index = require("../track/index.cjs");
5
5
  const require_hooks_use_outbound_click_analytics = require("../hooks/use-outbound-click-analytics.cjs");
6
+ const require_hooks_use_uet_id_sync = require("../hooks/use-uet-id-sync.cjs");
6
7
  const require_hooks_use_web_analytics = require("../hooks/use-web-analytics.cjs");
7
8
  let react = require("react");
8
9
  let next_navigation_js = require("next/navigation.js");
@@ -22,8 +23,9 @@ function PageViews() {
22
23
  require_hooks_use_web_analytics.useWebAnalytics(pathname, searchParams.toString());
23
24
  return null;
24
25
  }
25
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals = true }) {
26
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, facebookAppId, reportWebVitals = true }) {
26
27
  require_hooks_use_outbound_click_analytics.useOutboundClickAnalytics();
28
+ require_hooks_use_uet_id_sync.useUETIdSync(uetCustomerId);
27
29
  (0, next_web_vitals_js.useReportWebVitals)((metric) => {
28
30
  if (!reportWebVitals) return;
29
31
  const properties = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["usePathname","useSearchParams","Suspense","Script"],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname, useSearchParams } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\nimport { Suspense } from 'react';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n hotjarId?: `${number}`;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\n/**\n * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route\n * bails the whole tree out to client rendering unless something above it suspends, and Next\n * fails the build for a page that lets it. The boundary is here so a host does not have to know.\n */\nfunction PageViews() {\n const pathname = usePathname();\n const searchParams = useSearchParams();\n useWebAnalytics(pathname, searchParams.toString());\n return null;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n hotjarId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n useOutboundClickAnalytics();\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n <Suspense fallback={null}>\n <PageViews />\n </Suspense>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <Script\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <Script\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <Script\n id=\"meta-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <Script\n id=\"reddit-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <Script\n id=\"linkedin-insight-tag\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){ \n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <Script\n strategy=\"afterInteractive\"\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <Script\n id=\"hotjar\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkCA,SAAS,YAAY;CACnB,MAAM,YAAA,GAAWA,mBAAAA,YAAAA,CAAY;CAC7B,MAAM,gBAAA,GAAeC,mBAAAA,gBAAAA,CAAgB;CACrC,gCAAA,gBAAgB,UAAU,aAAa,SAAS,CAAC;CACjD,OAAO;AACT;AAEA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,kBAAkB,QACV;CACR,2CAAA,0BAA0B;CAE1B,CAAA,GAAA,mBAAA,mBAAA,EAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,oBAAA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,MAAAA,UAAD;GAAU,UAAU;GAClB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,CAAY,CAAA;EACJ,CAAA;EACT,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,eAAAA,SAAD;GACE,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACS;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;wCACoB,kBAAkB;;;;;;;;;;;;;;;;;gBAkBhD;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,UAAS;GACT,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"index.cjs","names":["usePathname","useSearchParams","Suspense","Script"],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname, useSearchParams } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\nimport { Suspense } from 'react';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useUETIdSync } from '../hooks/use-uet-id-sync';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n hotjarId?: `${number}`;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */\n uetCustomerId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\n/**\n * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route\n * bails the whole tree out to client rendering unless something above it suspends, and Next\n * fails the build for a page that lets it. The boundary is here so a host does not have to know.\n */\nfunction PageViews() {\n const pathname = usePathname();\n const searchParams = useSearchParams();\n useWebAnalytics(pathname, searchParams.toString());\n return null;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n hotjarId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n uetCustomerId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n useOutboundClickAnalytics();\n useUETIdSync(uetCustomerId);\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n <Suspense fallback={null}>\n <PageViews />\n </Suspense>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <Script\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <Script\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <Script\n id=\"meta-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <Script\n id=\"reddit-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <Script\n id=\"linkedin-insight-tag\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){ \n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <Script\n strategy=\"afterInteractive\"\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <Script\n id=\"hotjar\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqCA,SAAS,YAAY;CACnB,MAAM,YAAA,GAAWA,mBAAAA,YAAAA,CAAY;CAC7B,MAAM,gBAAA,GAAeC,mBAAAA,gBAAAA,CAAgB;CACrC,gCAAA,gBAAgB,UAAU,aAAa,SAAS,CAAC;CACjD,OAAO;AACT;AAEA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,eACA,kBAAkB,QACV;CACR,2CAAA,0BAA0B;CAC1B,8BAAA,aAAa,aAAa;CAE1B,CAAA,GAAA,mBAAA,mBAAA,EAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,oBAAA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,MAAAA,UAAD;GAAU,UAAU;GAClB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,CAAY,CAAA;EACJ,CAAA;EACT,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,eAAAA,SAAD;GACE,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACS;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;wCACoB,kBAAkB;;;;;;;;;;;;;;;;;gBAkBhD;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,UAAS;GACT,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAACA,eAAAA,SAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
@@ -12,12 +12,14 @@ interface Props {
12
12
  linkedInPartnerId?: `${number}`;
13
13
  /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
14
14
  uetTagId?: `${number}`;
15
+ /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */
16
+ uetCustomerId?: `${number}`;
15
17
  facebookAppId?: string;
16
18
  nonce?: string;
17
19
  debugMode?: boolean;
18
20
  reportWebVitals?: boolean;
19
21
  }
20
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
22
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
21
23
  //#endregion
22
24
  export { Analytics };
23
25
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAaU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;;EAEA;EACA;EACA;EACA;EACA;;iBAec,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,mBACC,wBAAK,IAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAcU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;;EAEA;;EAEA;EACA;EACA;EACA;EACA;;iBAec,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,eACA,mBACC,wBAAK,IAAA"}
@@ -12,12 +12,14 @@ interface Props {
12
12
  linkedInPartnerId?: `${number}`;
13
13
  /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
14
14
  uetTagId?: `${number}`;
15
+ /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */
16
+ uetCustomerId?: `${number}`;
15
17
  facebookAppId?: string;
16
18
  nonce?: string;
17
19
  debugMode?: boolean;
18
20
  reportWebVitals?: boolean;
19
21
  }
20
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
22
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
21
23
  //#endregion
22
24
  export { Analytics };
23
25
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAaU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;;EAEA;EACA;EACA;EACA;EACA;;iBAec,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,mBACC,wBAAK,IAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAcU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;;EAEA;;EAEA;EACA;EACA;EACA;EACA;;iBAec,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,eACA,mBACC,wBAAK,IAAA"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { track } from "../track/index.mjs";
3
3
  import { useOutboundClickAnalytics } from "../hooks/use-outbound-click-analytics.mjs";
4
+ import { useUETIdSync } from "../hooks/use-uet-id-sync.mjs";
4
5
  import { useWebAnalytics } from "../hooks/use-web-analytics.mjs";
5
6
  import { Suspense } from "react";
6
7
  import { usePathname, useSearchParams } from "next/navigation.js";
@@ -19,8 +20,9 @@ function PageViews() {
19
20
  useWebAnalytics(pathname, searchParams.toString());
20
21
  return null;
21
22
  }
22
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals = true }) {
23
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, facebookAppId, reportWebVitals = true }) {
23
24
  useOutboundClickAnalytics();
25
+ useUETIdSync(uetCustomerId);
24
26
  useReportWebVitals((metric) => {
25
27
  if (!reportWebVitals) return;
26
28
  const properties = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname, useSearchParams } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\nimport { Suspense } from 'react';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n hotjarId?: `${number}`;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\n/**\n * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route\n * bails the whole tree out to client rendering unless something above it suspends, and Next\n * fails the build for a page that lets it. The boundary is here so a host does not have to know.\n */\nfunction PageViews() {\n const pathname = usePathname();\n const searchParams = useSearchParams();\n useWebAnalytics(pathname, searchParams.toString());\n return null;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n hotjarId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n useOutboundClickAnalytics();\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n <Suspense fallback={null}>\n <PageViews />\n </Suspense>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <Script\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <Script\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <Script\n id=\"meta-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <Script\n id=\"reddit-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <Script\n id=\"linkedin-insight-tag\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){ \n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <Script\n strategy=\"afterInteractive\"\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <Script\n id=\"hotjar\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,SAAS,YAAY;CACnB,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAe,gBAAgB;CACrC,gBAAgB,UAAU,aAAa,SAAS,CAAC;CACjD,OAAO;AACT;AAEA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,kBAAkB,QACV;CACR,0BAA0B;CAE1B,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,UAAD;GAAU,UAAU;GAClB,UAAA,oBAAC,WAAD,CAAY,CAAA;EACJ,CAAA;EACT,iBAAiB,oBAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GACE,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,oBAAC,QAAD;GACS;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;wCACoB,kBAAkB;;;;;;;;;;;;;;;;;gBAkBhD;EACD,CAAA;EAEF,YACC,oBAAC,QAAD;GACE,UAAS;GACT,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname, useSearchParams } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\nimport { Suspense } from 'react';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useUETIdSync } from '../hooks/use-uet-id-sync';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n hotjarId?: `${number}`;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */\n uetCustomerId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\n/**\n * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route\n * bails the whole tree out to client rendering unless something above it suspends, and Next\n * fails the build for a page that lets it. The boundary is here so a host does not have to know.\n */\nfunction PageViews() {\n const pathname = usePathname();\n const searchParams = useSearchParams();\n useWebAnalytics(pathname, searchParams.toString());\n return null;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n hotjarId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n uetCustomerId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n useOutboundClickAnalytics();\n useUETIdSync(uetCustomerId);\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n <Suspense fallback={null}>\n <PageViews />\n </Suspense>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <Script\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <Script\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <Script\n id=\"meta-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <Script\n id=\"reddit-pixel\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <Script\n id=\"linkedin-insight-tag\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){ \n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <Script\n strategy=\"afterInteractive\"\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <Script\n id=\"hotjar\"\n strategy=\"afterInteractive\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,SAAS,YAAY;CACnB,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAe,gBAAgB;CACrC,gBAAgB,UAAU,aAAa,SAAS,CAAC;CACjD,OAAO;AACT;AAEA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,UACA,eACA,eACA,kBAAkB,QACV;CACR,0BAA0B;CAC1B,aAAa,aAAa;CAE1B,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,UAAD;GAAU,UAAU;GAClB,UAAA,oBAAC,WAAD,CAAY,CAAA;EACJ,CAAA;EACT,iBAAiB,oBAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GACE,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,oBAAC,QAAD;GACS;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;wCACoB,kBAAkB;;;;;;;;;;;;;;;;;gBAkBhD;EACD,CAAA;EAEF,YACC,oBAAC,QAAD;GACE,UAAS;GACT,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,oBAAC,QAAD;GACE,IAAG;GACH,UAAS;GACT,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
@@ -2,14 +2,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_track_index = require("../track/index.cjs");
3
3
  const require_hooks_use_outbound_click_analytics = require("../hooks/use-outbound-click-analytics.cjs");
4
4
  const require_hooks_use_report_web_vitals = require("../hooks/use-report-web-vitals.cjs");
5
+ const require_hooks_use_uet_id_sync = require("../hooks/use-uet-id-sync.cjs");
5
6
  const require_hooks_use_web_analytics = require("../hooks/use-web-analytics.cjs");
6
7
  let react_jsx_runtime = require("react/jsx-runtime");
7
8
  let react_router = require("react-router");
8
9
  //#region src/react-router/index.tsx
9
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals = true }) {
10
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, hotjarId, facebookAppId, reportWebVitals = true }) {
10
11
  const { pathname, search } = (0, react_router.useLocation)();
11
12
  require_hooks_use_web_analytics.useWebAnalytics(pathname, search);
12
13
  require_hooks_use_outbound_click_analytics.useOutboundClickAnalytics();
14
+ require_hooks_use_uet_id_sync.useUETIdSync(uetCustomerId);
13
15
  require_hooks_use_report_web_vitals.useReportWebVitals((metric) => {
14
16
  if (!reportWebVitals) return;
15
17
  const properties = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useLocation"],"sources":["../../src/react-router/index.tsx"],"sourcesContent":["import { useLocation } from 'react-router';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useReportWebVitals } from '../hooks/use-report-web-vitals';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n hotjarId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n hotjarId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const { pathname, search } = useLocation();\n useWebAnalytics(pathname, search);\n useOutboundClickAnalytics();\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <script\n async\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <script\n async\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <script\n async\n id=\"meta-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <script\n async\n id=\"reddit-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <script\n async\n id=\"linkedin-insight-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){\n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <script\n async\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <script\n async\n id=\"hotjar\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;AAyBA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,UACA,eACA,kBAAkB,QACV;CACR,MAAM,EAAE,UAAU,YAAA,GAAWA,aAAAA,YAAAA,CAAY;CACzC,gCAAA,gBAAgB,UAAU,MAAM;CAChC,2CAAA,0BAA0B;CAE1B,oCAAA,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,oBAAA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACG,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACO;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;sCACkB,kBAAkB;;;;;;;;;;;;;;;;;cAkB9C;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"index.cjs","names":["useLocation"],"sources":["../../src/react-router/index.tsx"],"sourcesContent":["import { useLocation } from 'react-router';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useReportWebVitals } from '../hooks/use-report-web-vitals';\nimport { useUETIdSync } from '../hooks/use-uet-id-sync';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */\n uetCustomerId?: `${number}`;\n hotjarId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n uetCustomerId,\n hotjarId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const { pathname, search } = useLocation();\n useWebAnalytics(pathname, search);\n useOutboundClickAnalytics();\n useUETIdSync(uetCustomerId);\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <script\n async\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <script\n async\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <script\n async\n id=\"meta-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <script\n async\n id=\"reddit-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <script\n async\n id=\"linkedin-insight-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){\n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <script\n async\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <script\n async\n id=\"hotjar\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;AA4BA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,UACA,eACA,kBAAkB,QACV;CACR,MAAM,EAAE,UAAU,YAAA,GAAWA,aAAAA,YAAAA,CAAY;CACzC,gCAAA,gBAAgB,UAAU,MAAM;CAChC,2CAAA,0BAA0B;CAC1B,8BAAA,aAAa,aAAa;CAE1B,oCAAA,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,oBAAA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACG,iBAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACO;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;sCACkB,kBAAkB;;;;;;;;;;;;;;;;;cAkB9C;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
@@ -11,13 +11,15 @@ interface Props {
11
11
  linkedInPartnerId?: `${number}`;
12
12
  /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
13
13
  uetTagId?: `${number}`;
14
+ /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */
15
+ uetCustomerId?: `${number}`;
14
16
  hotjarId?: `${number}`;
15
17
  facebookAppId?: string;
16
18
  nonce?: string;
17
19
  debugMode?: boolean;
18
20
  reportWebVitals?: boolean;
19
21
  }
20
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
22
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
21
23
  //#endregion
22
24
  export { Analytics };
23
25
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/react-router/index.tsx"],"mappings":";;;;UASU;EACR,OAAO;EACP;EACA,QAAQ;EACR,cAAc;EACd,gBAAgB;EAChB;;EAEA;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,UACA,eACA,mBACC,wBAAK,IAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/react-router/index.tsx"],"mappings":";;;;UAUU;EACR,OAAO;EACP;EACA,QAAQ;EACR,cAAc;EACd,gBAAgB;EAChB;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,UACA,eACA,mBACC,wBAAK,IAAA"}
@@ -11,13 +11,15 @@ interface Props {
11
11
  linkedInPartnerId?: `${number}`;
12
12
  /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
13
13
  uetTagId?: `${number}`;
14
+ /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */
15
+ uetCustomerId?: `${number}`;
14
16
  hotjarId?: `${number}`;
15
17
  facebookAppId?: string;
16
18
  nonce?: string;
17
19
  debugMode?: boolean;
18
20
  reportWebVitals?: boolean;
19
21
  }
20
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
22
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
21
23
  //#endregion
22
24
  export { Analytics };
23
25
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react-router/index.tsx"],"mappings":";;;;UASU;EACR,OAAO;EACP;EACA,QAAQ;EACR,cAAc;EACd,gBAAgB;EAChB;;EAEA;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,UACA,eACA,mBACC,wBAAK,IAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react-router/index.tsx"],"mappings":";;;;UAUU;EACR,OAAO;EACP;EACA,QAAQ;EACR,cAAc;EACd,gBAAgB;EAChB;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,UACA,eACA,mBACC,wBAAK,IAAA"}
@@ -1,14 +1,16 @@
1
1
  import { track } from "../track/index.mjs";
2
2
  import { useOutboundClickAnalytics } from "../hooks/use-outbound-click-analytics.mjs";
3
3
  import { useReportWebVitals } from "../hooks/use-report-web-vitals.mjs";
4
+ import { useUETIdSync } from "../hooks/use-uet-id-sync.mjs";
4
5
  import { useWebAnalytics } from "../hooks/use-web-analytics.mjs";
5
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
7
  import { useLocation } from "react-router";
7
8
  //#region src/react-router/index.tsx
8
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals = true }) {
9
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, uetCustomerId, hotjarId, facebookAppId, reportWebVitals = true }) {
9
10
  const { pathname, search } = useLocation();
10
11
  useWebAnalytics(pathname, search);
11
12
  useOutboundClickAnalytics();
13
+ useUETIdSync(uetCustomerId);
12
14
  useReportWebVitals((metric) => {
13
15
  if (!reportWebVitals) return;
14
16
  const properties = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.tsx"],"sourcesContent":["import { useLocation } from 'react-router';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useReportWebVitals } from '../hooks/use-report-web-vitals';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n hotjarId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n hotjarId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const { pathname, search } = useLocation();\n useWebAnalytics(pathname, search);\n useOutboundClickAnalytics();\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <script\n async\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <script\n async\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <script\n async\n id=\"meta-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <script\n async\n id=\"reddit-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <script\n async\n id=\"linkedin-insight-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){\n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <script\n async\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <script\n async\n id=\"hotjar\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;AAyBA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,UACA,eACA,kBAAkB,QACV;CACR,MAAM,EAAE,UAAU,WAAW,YAAY;CACzC,gBAAgB,UAAU,MAAM;CAChC,0BAA0B;CAE1B,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,iBAAiB,oBAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,oBAAC,UAAD;GACE,OAAA;GACO;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;sCACkB,kBAAkB;;;;;;;;;;;;;;;;;cAkB9C;EACD,CAAA;EAEF,YACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.tsx"],"sourcesContent":["import { useLocation } from 'react-router';\nimport { useOutboundClickAnalytics } from '../hooks/use-outbound-click-analytics';\nimport { useReportWebVitals } from '../hooks/use-report-web-vitals';\nimport { useUETIdSync } from '../hooks/use-uet-id-sync';\nimport { useWebAnalytics } from '../hooks/use-web-analytics';\nimport type { PixelId as MetaPixelId } from '../track/fbq';\nimport type { GaId, GtmId } from '../track/gtag';\nimport { track } from '../track/index';\nimport type { PixelId as RedditPixelId } from '../track/rdt';\n\ninterface Props {\n gaId?: GaId;\n gaSrc?: string;\n gtmId?: GtmId;\n metaPixelId?: MetaPixelId;\n redditPixelId?: RedditPixelId;\n linkedInPartnerId?: `${number}`;\n /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */\n uetTagId?: `${number}`;\n /** Microsoft Advertising customer id (`cid` in the ads UI's URLs): enables the Conversions API's ID Sync pixel. */\n uetCustomerId?: `${number}`;\n hotjarId?: `${number}`;\n facebookAppId?: string;\n nonce?: string;\n debugMode?: boolean;\n reportWebVitals?: boolean;\n}\n\nexport function Analytics({\n gaId,\n gaSrc,\n nonce,\n debugMode,\n metaPixelId,\n redditPixelId,\n linkedInPartnerId,\n uetTagId,\n uetCustomerId,\n hotjarId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const { pathname, search } = useLocation();\n useWebAnalytics(pathname, search);\n useOutboundClickAnalytics();\n useUETIdSync(uetCustomerId);\n\n useReportWebVitals((metric) => {\n if (!reportWebVitals) return;\n const properties = {\n value: metric.delta,\n metric_id: metric.id,\n metric_value: metric.value,\n metric_delta: metric.delta,\n metric_rating: metric.rating,\n metric_navigation_type: metric.navigationType,\n non_interaction: true, // avoids affecting bounce rate.\n };\n track(metric.name, properties);\n });\n\n return (\n <>\n {facebookAppId && <meta property=\"fb:app_id\" content={facebookAppId} />}\n {gaId && (\n <>\n <script\n async\n id=\"gtag\"\n nonce={nonce}\n src={gaSrc ?? `https://www.googletagmanager.com/gtag/js?id=${gaId}`}\n />\n <script\n async\n nonce={nonce}\n id=\"gtag-init\"\n dangerouslySetInnerHTML={{\n __html: `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', '${gaId}'${debugMode ? \" ,{ 'debug_mode': true }\" : ''});\n `,\n }}\n />\n </>\n )}\n {metaPixelId && (\n <script\n async\n id=\"meta-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !(function (f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function () {\n n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s);\n })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', '${metaPixelId}');\n fbq('track', 'PageView');`,\n }}\n />\n )}\n {redditPixelId && (\n <script\n async\n id=\"reddit-pixel\"\n dangerouslySetInnerHTML={{\n __html: `\n !function(w,d) {\n if(!w.rdt) {\n var p = w.rdt = function() {\n p.sendEvent ? p.sendEvent.apply(p,arguments) : p.callQueue.push(arguments)\n };\n p.callQueue = [];\n var t = d.createElement(\"script\");\n t.src = \"https://www.redditstatic.com/ads/pixel.js\";\n t.async = !0;\n var s = d.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(t,s)\n }\n }(window, document);\n rdt('init', '${redditPixelId}');\n rdt('track', 'PageVisit');`,\n }}\n />\n )}\n {linkedInPartnerId && (\n <script\n async\n id=\"linkedin-insight-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n _linkedin_partner_id = \"${linkedInPartnerId}\";\n window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];\n window._linkedin_data_partner_ids.push(_linkedin_partner_id);\n\n (function(l) {\n if (!l){\n window.lintrk = function(a,b){\n window.lintrk.q.push([a,b])\n };\n window.lintrk.q=[]\n }\n var s = document.getElementsByTagName(\"script\")[0];\n var b = document.createElement(\"script\");\n b.type = \"text/javascript\";b.async = true;\n b.src = \"https://snap.licdn.com/li.lms-analytics/insight.min.js\";\n s.parentNode.insertBefore(b, s);\n })(window.lintrk);\n `,\n }}\n />\n )}\n {uetTagId && (\n <script\n async\n id=\"uet-tag\"\n dangerouslySetInnerHTML={{\n __html: `\n (function (w, d, t, u, o) {\n w[u] = w[u] || [], o.ts = (new Date).getTime();\n var n = d.createElement(t);\n n.src = \"https://bat.bing.net/bat.js?ti=\" + o.ti + (\"uetq\" != u ? \"&q=\" + u : \"\"),\n n.async = 1, n.onload = n.onreadystatechange = function() {\n var s = this.readyState;\n s && \"loaded\" !== s && \"complete\" !== s ||\n (o.q = w[u], w[u] = new UET(o), w[u].push(\"pageLoad\"),\n n.onload = n.onreadystatechange = null)\n };\n var i = d.getElementsByTagName(t)[0];\n i.parentNode.insertBefore(n, i);\n })(window, document, \"script\", \"uetq\", {\n ti: \"${uetTagId}\",\n enableAutoSpaTracking: true\n });\n `,\n }}\n />\n )}\n {hotjarId && (\n <script\n async\n id=\"hotjar\"\n dangerouslySetInnerHTML={{\n __html: `\n (function(h,o,t,j,a,r){\n h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};\n h._hjSettings={hjid:${hotjarId},hjsv:6};\n a=o.getElementsByTagName('head')[0];\n r=o.createElement('script');r.async=1;\n r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;\n a.appendChild(r);\n })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');\n `,\n }}\n />\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;AA4BA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,UACA,eACA,kBAAkB,QACV;CACR,MAAM,EAAE,UAAU,WAAW,YAAY;CACzC,gBAAgB,UAAU,MAAM;CAChC,0BAA0B;CAC1B,aAAa,aAAa;CAE1B,oBAAoB,WAAW;EAC7B,IAAI,CAAC,iBAAiB;EACtB,MAAM,aAAa;GACjB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,wBAAwB,OAAO;GAC/B,iBAAiB;EACnB;EACA,MAAM,OAAO,MAAM,UAAU;CAC/B,CAAC;CAED,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,iBAAiB,oBAAC,QAAD;GAAM,UAAS;GAAY,SAAS;EAAgB,CAAA;EACrE,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACI;GACP,KAAK,SAAS,+CAA+C;EAC9D,CAAA,GACD,oBAAC,UAAD;GACE,OAAA;GACO;GACP,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;gCAIU,KAAK,GAAG,YAAY,6BAA6B,GAAG;cAExE;EACD,CAAA,CACD,EAAA,CAAA;EAEH,eACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;;;;2BAiBO,YAAY;uCAE7B;EACD,CAAA;EAEF,iBACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;2BAcO,cAAc;wCAE/B;EACD,CAAA;EAEF,qBACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;sCACkB,kBAAkB;;;;;;;;;;;;;;;;;cAkB9C;EACD,CAAA;EAEF,YACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;;;;;;;;;;;;uBAcG,SAAS;;;cAItB;EACD,CAAA;EAEF,YACC,oBAAC,UAAD;GACE,OAAA;GACA,IAAG;GACH,yBAAyB,EACvB,QAAQ;;;oCAGgB,SAAS;;;;;;cAOnC;EACD,CAAA;CAEH,EAAA,CAAA;AAEN"}
@@ -6,23 +6,45 @@ let node_crypto = require("node:crypto");
6
6
  //#region src/server/linkedin-conversions-api.ts
7
7
  /**
8
8
  * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder
9
- * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09
9
+ * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2026-09
10
10
  */
11
+ /**
12
+ * The schema prescribes an exact normalization per field before hashing, and getting it wrong is
13
+ * silent: LinkedIn accepts any 64-char hex digest and simply matches nobody. So these helpers are
14
+ * the difference between attribution and nothing, not between 200 and 400.
15
+ */
16
+ const sha256 = (value) => (0, node_crypto.createHash)("sha256").update(value).digest("hex");
17
+ /**
18
+ * An email is lower-cased and stripped of whitespace before hashing. Punctuation is left alone —
19
+ * `@` and `.` are the address.
20
+ */
21
+ const hashEmail = (email) => sha256(email.toLowerCase().replace(/\s/g, ""));
22
+ /**
23
+ * A name is lower-cased and stripped of whitespace *and punctuation* before hashing, so that
24
+ * `O'Brien`, `o brien` and `obrien` all land on the same digest. UTF-8 is what `update` already
25
+ * encodes with.
26
+ *
27
+ * The schema's wording ("lowercase with no spaces or punctuation") leaves room to read the
28
+ * apostrophe either way, so this is checked against its own worked example rather than guessed:
29
+ * the `hashedFirstName` / `hashedLastName` digests it prints are sha256('mary') and
30
+ * sha256('obrien') — Mary O'Brien with the apostrophe removed, not escaped or kept.
31
+ */
32
+ const hashName = (name) => sha256(name.toLowerCase().replace(/[\s\p{P}]/gu, ""));
11
33
  async function sendEvents(accessToken, config, events, data = {}) {
12
34
  const eventNames = Object.keys(config);
13
35
  const address = require_utils_field.getFirst(data.address);
14
36
  const userIds = [];
15
37
  const externalIds = data.user_id ? [data.user_id] : void 0;
16
38
  const userInfo = address?.first_name && address.last_name ? {
17
- firstName: address.first_name,
18
- lastName: address.last_name,
39
+ hashedFirstName: hashName(address.first_name),
40
+ hashedLastName: hashName(address.last_name),
19
41
  countryCode: address.country
20
42
  } : void 0;
21
43
  if (data.email) {
22
44
  const email = require_utils_field.getFirst(data.email);
23
45
  if (email) userIds.push({
24
46
  idType: "SHA256_EMAIL",
25
- idValue: (0, node_crypto.createHash)("sha256").update(email).digest("hex")
47
+ idValue: hashEmail(email)
26
48
  });
27
49
  }
28
50
  const dto = { elements: events.filter((event) => eventNames.includes(event.name) && !require_third_parties_ignored_events.IGNORED_EVENTS.includes(event.name)).map((event) => ({
@@ -41,7 +63,7 @@ async function sendEvents(accessToken, config, events, data = {}) {
41
63
  userInfo,
42
64
  externalIds
43
65
  }
44
- })) };
66
+ })).filter(({ user }) => user.userIds.length > 0 || !!user.userInfo || !!user.externalIds || !!user.lead) };
45
67
  if (dto.elements.length === 0) return;
46
68
  try {
47
69
  const response = await (0, _shware_utils.fetch)("https://api.linkedin.com/rest/conversionEvents", {
@@ -49,7 +71,7 @@ async function sendEvents(accessToken, config, events, data = {}) {
49
71
  headers: {
50
72
  Authorization: `Bearer ${accessToken}`,
51
73
  "Content-Type": "application/json",
52
- "LinkedIn-Version": "202509",
74
+ "LinkedIn-Version": "202609",
53
75
  "X-Restli-Protocol-Version": "2.0.0",
54
76
  "X-RestLi-Method": "BATCH_CREATE"
55
77
  },