@shware/analytics 8.2.0 → 8.5.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 (128) hide show
  1. package/README.md +78 -2
  2. package/dist/click-id/index.cjs +57 -3
  3. package/dist/click-id/index.cjs.map +1 -1
  4. package/dist/click-id/index.d.cts +16 -1
  5. package/dist/click-id/index.d.cts.map +1 -1
  6. package/dist/click-id/index.d.mts +16 -1
  7. package/dist/click-id/index.d.mts.map +1 -1
  8. package/dist/click-id/index.mjs +54 -4
  9. package/dist/click-id/index.mjs.map +1 -1
  10. package/dist/hooks/use-web-analytics.cjs +11 -5
  11. package/dist/hooks/use-web-analytics.cjs.map +1 -1
  12. package/dist/hooks/use-web-analytics.d.cts +4 -1
  13. package/dist/hooks/use-web-analytics.d.cts.map +1 -1
  14. package/dist/hooks/use-web-analytics.d.mts +4 -1
  15. package/dist/hooks/use-web-analytics.d.mts.map +1 -1
  16. package/dist/hooks/use-web-analytics.mjs +11 -5
  17. package/dist/hooks/use-web-analytics.mjs.map +1 -1
  18. package/dist/next/index.cjs +38 -2
  19. package/dist/next/index.cjs.map +1 -1
  20. package/dist/next/index.d.cts +3 -1
  21. package/dist/next/index.d.cts.map +1 -1
  22. package/dist/next/index.d.mts +3 -1
  23. package/dist/next/index.d.mts.map +1 -1
  24. package/dist/next/index.mjs +39 -3
  25. package/dist/next/index.mjs.map +1 -1
  26. package/dist/react-router/index.cjs +25 -3
  27. package/dist/react-router/index.cjs.map +1 -1
  28. package/dist/react-router/index.d.cts +3 -1
  29. package/dist/react-router/index.d.cts.map +1 -1
  30. package/dist/react-router/index.d.mts +3 -1
  31. package/dist/react-router/index.d.mts.map +1 -1
  32. package/dist/react-router/index.mjs +25 -3
  33. package/dist/react-router/index.mjs.map +1 -1
  34. package/dist/schema/index.cjs +1 -0
  35. package/dist/schema/index.cjs.map +1 -1
  36. package/dist/schema/index.d.cts +4 -0
  37. package/dist/schema/index.d.cts.map +1 -1
  38. package/dist/schema/index.d.mts +4 -0
  39. package/dist/schema/index.d.mts.map +1 -1
  40. package/dist/schema/index.mjs +1 -0
  41. package/dist/schema/index.mjs.map +1 -1
  42. package/dist/server/google-data-manager.cjs +2 -0
  43. package/dist/server/google-data-manager.cjs.map +1 -1
  44. package/dist/server/google-data-manager.d.cts.map +1 -1
  45. package/dist/server/google-data-manager.d.mts.map +1 -1
  46. package/dist/server/google-data-manager.mjs +2 -0
  47. package/dist/server/google-data-manager.mjs.map +1 -1
  48. package/dist/server/index.cjs +8 -0
  49. package/dist/server/index.d.cts +5 -4
  50. package/dist/server/index.d.mts +5 -4
  51. package/dist/server/index.mjs +5 -4
  52. package/dist/server/microsoft-conversions-api.cjs +171 -0
  53. package/dist/server/microsoft-conversions-api.cjs.map +1 -0
  54. package/dist/server/microsoft-conversions-api.d.cts +124 -0
  55. package/dist/server/microsoft-conversions-api.d.cts.map +1 -0
  56. package/dist/server/microsoft-conversions-api.d.mts +124 -0
  57. package/dist/server/microsoft-conversions-api.d.mts.map +1 -0
  58. package/dist/server/microsoft-conversions-api.mjs +168 -0
  59. package/dist/server/microsoft-conversions-api.mjs.map +1 -0
  60. package/dist/tanstack/analytics.cjs +25 -3
  61. package/dist/tanstack/analytics.cjs.map +1 -1
  62. package/dist/tanstack/analytics.d.cts +3 -1
  63. package/dist/tanstack/analytics.d.cts.map +1 -1
  64. package/dist/tanstack/analytics.d.mts +3 -1
  65. package/dist/tanstack/analytics.d.mts.map +1 -1
  66. package/dist/tanstack/analytics.mjs +25 -3
  67. package/dist/tanstack/analytics.mjs.map +1 -1
  68. package/dist/tanstack/middleware.cjs +2 -1
  69. package/dist/tanstack/middleware.cjs.map +1 -1
  70. package/dist/tanstack/middleware.d.cts +2 -1
  71. package/dist/tanstack/middleware.d.cts.map +1 -1
  72. package/dist/tanstack/middleware.d.mts +2 -1
  73. package/dist/tanstack/middleware.d.mts.map +1 -1
  74. package/dist/tanstack/middleware.mjs +2 -1
  75. package/dist/tanstack/middleware.mjs.map +1 -1
  76. package/dist/third-parties/index.cjs +5 -0
  77. package/dist/third-parties/index.d.cts +3 -1
  78. package/dist/third-parties/index.d.mts +3 -1
  79. package/dist/third-parties/index.mjs +2 -1
  80. package/dist/third-parties/microsoft-uet.cjs +119 -0
  81. package/dist/third-parties/microsoft-uet.cjs.map +1 -0
  82. package/dist/third-parties/microsoft-uet.d.cts +70 -0
  83. package/dist/third-parties/microsoft-uet.d.cts.map +1 -0
  84. package/dist/third-parties/microsoft-uet.d.mts +70 -0
  85. package/dist/third-parties/microsoft-uet.d.mts.map +1 -0
  86. package/dist/third-parties/microsoft-uet.mjs +115 -0
  87. package/dist/third-parties/microsoft-uet.mjs.map +1 -0
  88. package/dist/third-parties/openai-pixel.cjs +2 -7
  89. package/dist/third-parties/openai-pixel.cjs.map +1 -1
  90. package/dist/third-parties/openai-pixel.d.cts.map +1 -1
  91. package/dist/third-parties/openai-pixel.d.mts.map +1 -1
  92. package/dist/third-parties/openai-pixel.mjs +1 -6
  93. package/dist/third-parties/openai-pixel.mjs.map +1 -1
  94. package/dist/track/types.d.cts +7 -0
  95. package/dist/track/types.d.cts.map +1 -1
  96. package/dist/track/types.d.mts +7 -0
  97. package/dist/track/types.d.mts.map +1 -1
  98. package/dist/track/uetq.cjs +80 -0
  99. package/dist/track/uetq.cjs.map +1 -0
  100. package/dist/track/uetq.d.cts +111 -0
  101. package/dist/track/uetq.d.cts.map +1 -0
  102. package/dist/track/uetq.d.mts +111 -0
  103. package/dist/track/uetq.d.mts.map +1 -0
  104. package/dist/track/uetq.mjs +78 -0
  105. package/dist/track/uetq.mjs.map +1 -0
  106. package/dist/utils/sha256.cjs +19 -0
  107. package/dist/utils/sha256.cjs.map +1 -0
  108. package/dist/utils/sha256.d.cts +13 -0
  109. package/dist/utils/sha256.d.cts.map +1 -0
  110. package/dist/utils/sha256.d.mts +13 -0
  111. package/dist/utils/sha256.d.mts.map +1 -0
  112. package/dist/utils/sha256.mjs +18 -0
  113. package/dist/utils/sha256.mjs.map +1 -0
  114. package/dist/web/index.cjs +26 -2
  115. package/dist/web/index.cjs.map +1 -1
  116. package/dist/web/index.d.cts.map +1 -1
  117. package/dist/web/index.d.mts.map +1 -1
  118. package/dist/web/index.mjs +27 -3
  119. package/dist/web/index.mjs.map +1 -1
  120. package/dist/web/page-key.cjs +53 -0
  121. package/dist/web/page-key.cjs.map +1 -0
  122. package/dist/web/page-key.d.cts +24 -0
  123. package/dist/web/page-key.d.cts.map +1 -0
  124. package/dist/web/page-key.d.mts +24 -0
  125. package/dist/web/page-key.d.mts.map +1 -0
  126. package/dist/web/page-key.mjs +52 -0
  127. package/dist/web/page-key.mjs.map +1 -0
  128. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-analytics.cjs","names":["config","keys","getSession","usePrevious","useRef","throttle"],"sources":["../../src/hooks/use-web-analytics.ts"],"sourcesContent":["import { throttle } from '@shware/utils';\nimport { useEffect, useRef } from 'react';\nimport { keys } from '../constants/storage';\nimport { config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nfunction sendFirstVisit(pathname: string) {\n if (config.storage.getItem(keys.first_visit_time)) return;\n track('first_visit', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n });\n config.storage.setItem(keys.first_visit_time, new Date().toISOString());\n}\n\nfunction sendUserEngagement(trigger: 'pagehide' | 'visibilitychange') {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec, trigger });\n}\n\n/** Whether the event was actually sent — a zero-engagement crossing reports nothing. */\nfunction sendScroll(): boolean {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return false;\n track('scroll', { engagement_time_msec });\n return true;\n}\n\nfunction getScrollPercent() {\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return 0;\n return ((scrollTop + windowHeight) * 100) / docHeight;\n}\n\nfunction onPageHide() {\n getSession().pagehide();\n sendUserEngagement('pagehide');\n}\n\nfunction onVisibilityChange() {\n getSession().visibilitychange(document.visibilityState);\n if (document.visibilityState === 'hidden') {\n sendUserEngagement('visibilitychange');\n }\n}\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n\n // reset state when the pathname changes and send scroll when the user navigates to a new page\n const hasSendScroll = useRef(false);\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n // One lookup for the whole effect: `addEventListener` and its matching\n // `removeEventListener` have to be handed the very same function.\n const session = getSession();\n\n sendFirstVisit(pathname);\n\n const onScroll = throttle(() => {\n session.updateAccumulator();\n if (hasSendScroll.current) return;\n // only send scroll when the user has scrolled more than 90% of the page\n if (getScrollPercent() < 90) return;\n // A crossing with no engaged time (a restored scroll position in an unfocused window) must\n // not consume the page's one shot: the flag is set only once the event is actually sent.\n hasSendScroll.current = sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(session.updateAccumulator, 1000);\n\n window.addEventListener('focus', session.focus);\n window.addEventListener('blur', session.blur);\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('pageshow', session.pageshow);\n window.addEventListener('pagehide', onPageHide);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n // save checkpoint\n checkpointEvents.forEach((e) => {\n window.addEventListener(e, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', session.focus);\n window.removeEventListener('blur', session.blur);\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('pageshow', session.pageshow);\n window.removeEventListener('pagehide', onPageHide);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n checkpointEvents.forEach((e) => window.removeEventListener(e, checkpoint, { capture: true }));\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n\n useEffect(() => {\n track('page_view', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n engagement_time_msec: prevPathname ? getSession().flush() : undefined,\n });\n }, [pathname]);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAS,eAAe,UAAkB;CACxC,IAAIA,oBAAAA,OAAO,QAAQ,QAAQC,0BAAAA,KAAK,gBAAgB,GAAG;CACnD,oBAAA,MAAM,eAAe;EACnB,WAAW;EACX,YAAY,SAAS;EACrB,eAAe,SAAS;EACxB,eAAe,OAAO,SAAS;CACjC,CAAC;CACD,oBAAA,OAAO,QAAQ,QAAQA,0BAAAA,KAAK,mCAAkB,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC;AACxE;AAEA,SAAS,mBAAmB,SAA0C;CACpE,MAAM,uBAAuBC,sBAAAA,WAAW,CAAC,CAAC,MAAM;CAChD,IAAI,wBAAwB,GAAG;CAC/B,oBAAA,WAAW,mBAAmB;EAAE;EAAsB;CAAQ,CAAC;AACjE;;AAGA,SAAS,aAAsB;CAC7B,MAAM,uBAAuBA,sBAAAA,WAAW,CAAC,CAAC,MAAM;CAChD,IAAI,wBAAwB,GAAG,OAAO;CACtC,oBAAA,MAAM,UAAU,EAAE,qBAAqB,CAAC;CACxC,OAAO;AACT;AAEA,SAAS,mBAAmB;CAC1B,MAAM,YAAY,OAAO,WAAW,SAAS,gBAAgB;CAC7D,MAAM,eAAe,OAAO;CAC5B,MAAM,YAAY,SAAS,gBAAgB;CAC3C,IAAI,cAAc,GAAG,OAAO;CAC5B,QAAS,YAAY,gBAAgB,MAAO;AAC9C;AAEA,SAAS,aAAa;CACpB,sBAAA,WAAW,CAAC,CAAC,SAAS;CACtB,mBAAmB,UAAU;AAC/B;AAEA,SAAS,qBAAqB;CAC5B,sBAAA,WAAW,CAAC,CAAC,iBAAiB,SAAS,eAAe;CACtD,IAAI,SAAS,oBAAoB,UAC/B,mBAAmB,kBAAkB;AAEzC;;;;;;AAOA,SAAgB,gBAAgB,UAAkB;CAChD,MAAM,eAAeC,2BAAAA,YAAY,QAAQ;CAGzC,MAAM,iBAAA,GAAgBC,MAAAA,OAAAA,CAAO,KAAK;CAClC,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,cAAc,UAAU;CAC1B,GAAG,CAAC,QAAQ,CAAC;CAEb,CAAA,GAAA,MAAA,UAAA,OAAgB;EAGd,MAAM,UAAUF,sBAAAA,WAAW;EAE3B,eAAe,QAAQ;EAEvB,MAAM,YAAA,GAAWG,cAAAA,SAAAA,OAAe;GAC9B,QAAQ,kBAAkB;GAC1B,IAAI,cAAc,SAAS;GAE3B,IAAI,iBAAiB,IAAI,IAAI;GAG7B,cAAc,UAAU,WAAW;EACrC,GAAG,GAAG;EAEN,MAAM,mBAAmB;GAAC;GAAa;GAAW;EAAY;EAC9D,MAAM,cAAA,GAAaA,cAAAA,SAAAA,CAAS,QAAQ,mBAAmB,GAAI;EAE3D,OAAO,iBAAiB,SAAS,QAAQ,KAAK;EAC9C,OAAO,iBAAiB,QAAQ,QAAQ,IAAI;EAC5C,OAAO,iBAAiB,UAAU,UAAU,EAAE,SAAS,KAAK,CAAC;EAC7D,OAAO,iBAAiB,YAAY,QAAQ,QAAQ;EACpD,OAAO,iBAAiB,YAAY,UAAU;EAC9C,SAAS,iBAAiB,oBAAoB,kBAAkB;EAGhE,iBAAiB,SAAS,MAAM;GAC9B,OAAO,iBAAiB,GAAG,YAAY;IAAE,SAAS;IAAM,SAAS;GAAK,CAAC;EACzE,CAAC;EAED,aAAa;GACX,OAAO,oBAAoB,SAAS,QAAQ,KAAK;GACjD,OAAO,oBAAoB,QAAQ,QAAQ,IAAI;GAC/C,OAAO,oBAAoB,UAAU,QAAQ;GAC7C,OAAO,oBAAoB,YAAY,QAAQ,QAAQ;GACvD,OAAO,oBAAoB,YAAY,UAAU;GACjD,SAAS,oBAAoB,oBAAoB,kBAAkB;GACnE,iBAAiB,SAAS,MAAM,OAAO,oBAAoB,GAAG,YAAY,EAAE,SAAS,KAAK,CAAC,CAAC;GAE5F,SAAS,OAAO;GAChB,WAAW,OAAO;EACpB;CACF,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,oBAAA,MAAM,aAAa;GACjB,WAAW;GACX,YAAY,SAAS;GACrB,eAAe,SAAS;GACxB,eAAe,OAAO,SAAS;GAC/B,oBAAoB,gBAAgB,KAAA;GACpC,sBAAsB,eAAeH,sBAAAA,WAAW,CAAC,CAAC,MAAM,IAAI,KAAA;EAC9D,CAAC;CACH,GAAG,CAAC,QAAQ,CAAC;AACf"}
1
+ {"version":3,"file":"use-web-analytics.cjs","names":["config","keys","getSession","getPageKey","usePrevious","useRef","throttle"],"sources":["../../src/hooks/use-web-analytics.ts"],"sourcesContent":["import { throttle } from '@shware/utils';\nimport { useEffect, useRef } from 'react';\nimport { keys } from '../constants/storage';\nimport { config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\nimport { getPageKey } from '../web/page-key';\nimport { usePrevious } from './use-previous';\n\nfunction sendFirstVisit(pathname: string) {\n if (config.storage.getItem(keys.first_visit_time)) return;\n track('first_visit', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n });\n config.storage.setItem(keys.first_visit_time, new Date().toISOString());\n}\n\nfunction sendUserEngagement(trigger: 'pagehide' | 'visibilitychange') {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec, trigger });\n}\n\n/** Whether the event was actually sent — a zero-engagement crossing reports nothing. */\nfunction sendScroll(): boolean {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return false;\n track('scroll', { engagement_time_msec });\n return true;\n}\n\nfunction getScrollPercent() {\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return 0;\n return ((scrollTop + windowHeight) * 100) / docHeight;\n}\n\nfunction onPageHide() {\n getSession().pagehide();\n sendUserEngagement('pagehide');\n}\n\nfunction onVisibilityChange() {\n getSession().visibilitychange(document.visibilityState);\n if (document.visibilityState === 'hidden') {\n sendUserEngagement('visibilitychange');\n }\n}\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n * 4. send page_view when the page changes — path or query, see `getPageKey`; `search` is the\n * router's query string (`?a=1`, or `''`), required so no caller forgets that the query is\n * part of what makes a page\n */\nexport function useWebAnalytics(pathname: string, search: string) {\n const page = getPageKey(pathname, search);\n const prevPage = usePrevious(page);\n const prevPathname = usePrevious(pathname);\n\n // reset state when the page changes and send scroll when the user navigates to a new page\n const hasSendScroll = useRef(false);\n useEffect(() => {\n hasSendScroll.current = false;\n }, [page]);\n\n useEffect(() => {\n // One lookup for the whole effect: `addEventListener` and its matching\n // `removeEventListener` have to be handed the very same function.\n const session = getSession();\n\n sendFirstVisit(pathname);\n\n const onScroll = throttle(() => {\n session.updateAccumulator();\n if (hasSendScroll.current) return;\n // only send scroll when the user has scrolled more than 90% of the page\n if (getScrollPercent() < 90) return;\n // A crossing with no engaged time (a restored scroll position in an unfocused window) must\n // not consume the page's one shot: the flag is set only once the event is actually sent.\n hasSendScroll.current = sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(session.updateAccumulator, 1000);\n\n window.addEventListener('focus', session.focus);\n window.addEventListener('blur', session.blur);\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('pageshow', session.pageshow);\n window.addEventListener('pagehide', onPageHide);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n // save checkpoint\n checkpointEvents.forEach((e) => {\n window.addEventListener(e, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', session.focus);\n window.removeEventListener('blur', session.blur);\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('pageshow', session.pageshow);\n window.removeEventListener('pagehide', onPageHide);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n checkpointEvents.forEach((e) => window.removeEventListener(e, checkpoint, { capture: true }));\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n\n useEffect(() => {\n // `page_path` stays the path — the query is in `page_location` — and the previous page is\n // named by its path too, so a query-only change reports the same path as its predecessor.\n track('page_view', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPage === undefined ? undefined : prevPathname,\n engagement_time_msec: prevPage === undefined ? undefined : getSession().flush(),\n });\n }, [page]);\n}\n"],"mappings":"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"}
@@ -3,8 +3,11 @@
3
3
  * 1. send session_start event when the page is loaded
4
4
  * 2. send scroll event when the user scrolls more than 90% of the page
5
5
  * 3. send user_engagement event when the page is hidden or the user is not focused
6
+ * 4. send page_view when the page changes — path or query, see `getPageKey`; `search` is the
7
+ * router's query string (`?a=1`, or `''`), required so no caller forgets that the query is
8
+ * part of what makes a page
6
9
  */
7
- declare function useWebAnalytics(pathname: string): void;
10
+ declare function useWebAnalytics(pathname: string, search: string): void;
8
11
  //#endregion
9
12
  export { useWebAnalytics };
10
13
  //# sourceMappingURL=use-web-analytics.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-analytics.d.cts","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"mappings":";;;;;;iBA0DgB,gBAAgB"}
1
+ {"version":3,"file":"use-web-analytics.d.cts","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"mappings":";;;;;;;;;iBA8DgB,gBAAgB,kBAAkB"}
@@ -3,8 +3,11 @@
3
3
  * 1. send session_start event when the page is loaded
4
4
  * 2. send scroll event when the user scrolls more than 90% of the page
5
5
  * 3. send user_engagement event when the page is hidden or the user is not focused
6
+ * 4. send page_view when the page changes — path or query, see `getPageKey`; `search` is the
7
+ * router's query string (`?a=1`, or `''`), required so no caller forgets that the query is
8
+ * part of what makes a page
6
9
  */
7
- declare function useWebAnalytics(pathname: string): void;
10
+ declare function useWebAnalytics(pathname: string, search: string): void;
8
11
  //#endregion
9
12
  export { useWebAnalytics };
10
13
  //# sourceMappingURL=use-web-analytics.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-analytics.d.mts","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"mappings":";;;;;;iBA0DgB,gBAAgB"}
1
+ {"version":3,"file":"use-web-analytics.d.mts","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"mappings":";;;;;;;;;iBA8DgB,gBAAgB,kBAAkB"}
@@ -3,6 +3,7 @@ import { keys } from "../constants/storage.mjs";
3
3
  import { getSession } from "../setup/session.mjs";
4
4
  import { sendBeacon, track } from "../track/index.mjs";
5
5
  import { usePrevious } from "./use-previous.mjs";
6
+ import { getPageKey } from "../web/page-key.mjs";
6
7
  import { throttle } from "@shware/utils";
7
8
  import { useEffect, useRef } from "react";
8
9
  //#region src/hooks/use-web-analytics.ts
@@ -50,13 +51,18 @@ function onVisibilityChange() {
50
51
  * 1. send session_start event when the page is loaded
51
52
  * 2. send scroll event when the user scrolls more than 90% of the page
52
53
  * 3. send user_engagement event when the page is hidden or the user is not focused
54
+ * 4. send page_view when the page changes — path or query, see `getPageKey`; `search` is the
55
+ * router's query string (`?a=1`, or `''`), required so no caller forgets that the query is
56
+ * part of what makes a page
53
57
  */
54
- function useWebAnalytics(pathname) {
58
+ function useWebAnalytics(pathname, search) {
59
+ const page = getPageKey(pathname, search);
60
+ const prevPage = usePrevious(page);
55
61
  const prevPathname = usePrevious(pathname);
56
62
  const hasSendScroll = useRef(false);
57
63
  useEffect(() => {
58
64
  hasSendScroll.current = false;
59
- }, [pathname]);
65
+ }, [page]);
60
66
  useEffect(() => {
61
67
  const session = getSession();
62
68
  sendFirstVisit(pathname);
@@ -102,10 +108,10 @@ function useWebAnalytics(pathname) {
102
108
  page_title: document.title,
103
109
  page_referrer: document.referrer,
104
110
  page_location: window.location.href,
105
- previous_page_path: prevPathname ?? void 0,
106
- engagement_time_msec: prevPathname ? getSession().flush() : void 0
111
+ previous_page_path: prevPage === void 0 ? void 0 : prevPathname,
112
+ engagement_time_msec: prevPage === void 0 ? void 0 : getSession().flush()
107
113
  });
108
- }, [pathname]);
114
+ }, [page]);
109
115
  }
110
116
  //#endregion
111
117
  export { useWebAnalytics };
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-analytics.mjs","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"sourcesContent":["import { throttle } from '@shware/utils';\nimport { useEffect, useRef } from 'react';\nimport { keys } from '../constants/storage';\nimport { config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nfunction sendFirstVisit(pathname: string) {\n if (config.storage.getItem(keys.first_visit_time)) return;\n track('first_visit', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n });\n config.storage.setItem(keys.first_visit_time, new Date().toISOString());\n}\n\nfunction sendUserEngagement(trigger: 'pagehide' | 'visibilitychange') {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec, trigger });\n}\n\n/** Whether the event was actually sent — a zero-engagement crossing reports nothing. */\nfunction sendScroll(): boolean {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return false;\n track('scroll', { engagement_time_msec });\n return true;\n}\n\nfunction getScrollPercent() {\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return 0;\n return ((scrollTop + windowHeight) * 100) / docHeight;\n}\n\nfunction onPageHide() {\n getSession().pagehide();\n sendUserEngagement('pagehide');\n}\n\nfunction onVisibilityChange() {\n getSession().visibilitychange(document.visibilityState);\n if (document.visibilityState === 'hidden') {\n sendUserEngagement('visibilitychange');\n }\n}\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n\n // reset state when the pathname changes and send scroll when the user navigates to a new page\n const hasSendScroll = useRef(false);\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n // One lookup for the whole effect: `addEventListener` and its matching\n // `removeEventListener` have to be handed the very same function.\n const session = getSession();\n\n sendFirstVisit(pathname);\n\n const onScroll = throttle(() => {\n session.updateAccumulator();\n if (hasSendScroll.current) return;\n // only send scroll when the user has scrolled more than 90% of the page\n if (getScrollPercent() < 90) return;\n // A crossing with no engaged time (a restored scroll position in an unfocused window) must\n // not consume the page's one shot: the flag is set only once the event is actually sent.\n hasSendScroll.current = sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(session.updateAccumulator, 1000);\n\n window.addEventListener('focus', session.focus);\n window.addEventListener('blur', session.blur);\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('pageshow', session.pageshow);\n window.addEventListener('pagehide', onPageHide);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n // save checkpoint\n checkpointEvents.forEach((e) => {\n window.addEventListener(e, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', session.focus);\n window.removeEventListener('blur', session.blur);\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('pageshow', session.pageshow);\n window.removeEventListener('pagehide', onPageHide);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n checkpointEvents.forEach((e) => window.removeEventListener(e, checkpoint, { capture: true }));\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n\n useEffect(() => {\n track('page_view', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n engagement_time_msec: prevPathname ? getSession().flush() : undefined,\n });\n }, [pathname]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-web-analytics.mjs","names":[],"sources":["../../src/hooks/use-web-analytics.ts"],"sourcesContent":["import { throttle } from '@shware/utils';\nimport { useEffect, useRef } from 'react';\nimport { keys } from '../constants/storage';\nimport { config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\nimport { getPageKey } from '../web/page-key';\nimport { usePrevious } from './use-previous';\n\nfunction sendFirstVisit(pathname: string) {\n if (config.storage.getItem(keys.first_visit_time)) return;\n track('first_visit', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n });\n config.storage.setItem(keys.first_visit_time, new Date().toISOString());\n}\n\nfunction sendUserEngagement(trigger: 'pagehide' | 'visibilitychange') {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec, trigger });\n}\n\n/** Whether the event was actually sent — a zero-engagement crossing reports nothing. */\nfunction sendScroll(): boolean {\n const engagement_time_msec = getSession().flush();\n if (engagement_time_msec <= 0) return false;\n track('scroll', { engagement_time_msec });\n return true;\n}\n\nfunction getScrollPercent() {\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return 0;\n return ((scrollTop + windowHeight) * 100) / docHeight;\n}\n\nfunction onPageHide() {\n getSession().pagehide();\n sendUserEngagement('pagehide');\n}\n\nfunction onVisibilityChange() {\n getSession().visibilitychange(document.visibilityState);\n if (document.visibilityState === 'hidden') {\n sendUserEngagement('visibilitychange');\n }\n}\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n * 4. send page_view when the page changes — path or query, see `getPageKey`; `search` is the\n * router's query string (`?a=1`, or `''`), required so no caller forgets that the query is\n * part of what makes a page\n */\nexport function useWebAnalytics(pathname: string, search: string) {\n const page = getPageKey(pathname, search);\n const prevPage = usePrevious(page);\n const prevPathname = usePrevious(pathname);\n\n // reset state when the page changes and send scroll when the user navigates to a new page\n const hasSendScroll = useRef(false);\n useEffect(() => {\n hasSendScroll.current = false;\n }, [page]);\n\n useEffect(() => {\n // One lookup for the whole effect: `addEventListener` and its matching\n // `removeEventListener` have to be handed the very same function.\n const session = getSession();\n\n sendFirstVisit(pathname);\n\n const onScroll = throttle(() => {\n session.updateAccumulator();\n if (hasSendScroll.current) return;\n // only send scroll when the user has scrolled more than 90% of the page\n if (getScrollPercent() < 90) return;\n // A crossing with no engaged time (a restored scroll position in an unfocused window) must\n // not consume the page's one shot: the flag is set only once the event is actually sent.\n hasSendScroll.current = sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(session.updateAccumulator, 1000);\n\n window.addEventListener('focus', session.focus);\n window.addEventListener('blur', session.blur);\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('pageshow', session.pageshow);\n window.addEventListener('pagehide', onPageHide);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n // save checkpoint\n checkpointEvents.forEach((e) => {\n window.addEventListener(e, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', session.focus);\n window.removeEventListener('blur', session.blur);\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('pageshow', session.pageshow);\n window.removeEventListener('pagehide', onPageHide);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n checkpointEvents.forEach((e) => window.removeEventListener(e, checkpoint, { capture: true }));\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n\n useEffect(() => {\n // `page_path` stays the path — the query is in `page_location` — and the previous page is\n // named by its path too, so a query-only change reports the same path as its predecessor.\n track('page_view', {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPage === undefined ? undefined : prevPathname,\n engagement_time_msec: prevPage === undefined ? undefined : getSession().flush(),\n });\n }, [page]);\n}\n"],"mappings":"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"}
@@ -4,15 +4,25 @@ 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
6
  const require_hooks_use_web_analytics = require("../hooks/use-web-analytics.cjs");
7
+ let react = require("react");
7
8
  let next_navigation_js = require("next/navigation.js");
8
9
  let next_script_js = require("next/script.js");
9
10
  next_script_js = require_runtime.__toESM(next_script_js, 1);
10
11
  let next_web_vitals_js = require("next/web-vitals.js");
11
12
  let react_jsx_runtime = require("react/jsx-runtime");
12
13
  //#region src/next/index.tsx
13
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, facebookAppId, reportWebVitals = true }) {
14
+ /**
15
+ * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route
16
+ * bails the whole tree out to client rendering unless something above it suspends, and Next
17
+ * fails the build for a page that lets it. The boundary is here so a host does not have to know.
18
+ */
19
+ function PageViews() {
14
20
  const pathname = (0, next_navigation_js.usePathname)();
15
- require_hooks_use_web_analytics.useWebAnalytics(pathname);
21
+ const searchParams = (0, next_navigation_js.useSearchParams)();
22
+ require_hooks_use_web_analytics.useWebAnalytics(pathname, searchParams.toString());
23
+ return null;
24
+ }
25
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals = true }) {
16
26
  require_hooks_use_outbound_click_analytics.useOutboundClickAnalytics();
17
27
  (0, next_web_vitals_js.useReportWebVitals)((metric) => {
18
28
  if (!reportWebVitals) return;
@@ -28,6 +38,10 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, reddi
28
38
  require_track_index.track(metric.name, properties);
29
39
  });
30
40
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
41
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
42
+ fallback: null,
43
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageViews, {})
44
+ }),
31
45
  facebookAppId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
32
46
  property: "fb:app_id",
33
47
  content: facebookAppId
@@ -111,6 +125,28 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, reddi
111
125
  s.parentNode.insertBefore(b, s);
112
126
  })(window.lintrk);
113
127
  ` }
128
+ }),
129
+ uetTagId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(next_script_js.default, {
130
+ strategy: "afterInteractive",
131
+ id: "uet-tag",
132
+ dangerouslySetInnerHTML: { __html: `
133
+ (function (w, d, t, u, o) {
134
+ w[u] = w[u] || [], o.ts = (new Date).getTime();
135
+ var n = d.createElement(t);
136
+ n.src = "https://bat.bing.net/bat.js?ti=" + o.ti + ("uetq" != u ? "&q=" + u : ""),
137
+ n.async = 1, n.onload = n.onreadystatechange = function() {
138
+ var s = this.readyState;
139
+ s && "loaded" !== s && "complete" !== s ||
140
+ (o.q = w[u], w[u] = new UET(o), w[u].push("pageLoad"),
141
+ n.onload = n.onreadystatechange = null)
142
+ };
143
+ var i = d.getElementsByTagName(t)[0];
144
+ i.parentNode.insertBefore(n, i);
145
+ })(window, document, "script", "uetq", {
146
+ ti: "${uetTagId}",
147
+ enableAutoSpaTracking: true
148
+ });
149
+ ` }
114
150
  }),
115
151
  hotjarId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(next_script_js.default, {
116
152
  id: "hotjar",
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["usePathname","Script"],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\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 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 hotjarId,\n redditPixelId,\n linkedInPartnerId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const pathname = usePathname();\n useWebAnalytics(pathname);\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 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 {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":";;;;;;;;;;;;AA0BA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,eACA,kBAAkB,QACV;CACR,MAAM,YAAA,GAAWA,mBAAAA,YAAAA,CAAY;CAC7B,gCAAA,gBAAgB,QAAQ;CACxB,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;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,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,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 { 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"}
@@ -10,12 +10,14 @@ interface Props {
10
10
  metaPixelId?: PixelId;
11
11
  redditPixelId?: PixelId$1;
12
12
  linkedInPartnerId?: `${number}`;
13
+ /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
14
+ uetTagId?: `${number}`;
13
15
  facebookAppId?: string;
14
16
  nonce?: string;
15
17
  debugMode?: boolean;
16
18
  reportWebVitals?: boolean;
17
19
  }
18
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
20
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
19
21
  //#endregion
20
22
  export { Analytics };
21
23
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAYU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,eACA,mBACC,wBAAK,IAAA"}
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"}
@@ -10,12 +10,14 @@ interface Props {
10
10
  metaPixelId?: PixelId;
11
11
  redditPixelId?: PixelId$1;
12
12
  linkedInPartnerId?: `${number}`;
13
+ /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
14
+ uetTagId?: `${number}`;
13
15
  facebookAppId?: string;
14
16
  nonce?: string;
15
17
  debugMode?: boolean;
16
18
  reportWebVitals?: boolean;
17
19
  }
18
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
20
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
19
21
  //#endregion
20
22
  export { Analytics };
21
23
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/index.tsx"],"mappings":";;;;UAYU;EACR,OAAO;EACP;EACA,QAAQ;EACR;EACA,cAAc;EACd,gBAAgB;EAChB;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,eACA,mBACC,wBAAK,IAAA"}
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"}
@@ -2,14 +2,24 @@
2
2
  import { track } from "../track/index.mjs";
3
3
  import { useOutboundClickAnalytics } from "../hooks/use-outbound-click-analytics.mjs";
4
4
  import { useWebAnalytics } from "../hooks/use-web-analytics.mjs";
5
- import { usePathname } from "next/navigation.js";
5
+ import { Suspense } from "react";
6
+ import { usePathname, useSearchParams } from "next/navigation.js";
6
7
  import Script from "next/script.js";
7
8
  import { useReportWebVitals } from "next/web-vitals.js";
8
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region src/next/index.tsx
10
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, facebookAppId, reportWebVitals = true }) {
11
+ /**
12
+ * Its own component under a Suspense boundary: `useSearchParams` in a statically rendered route
13
+ * bails the whole tree out to client rendering unless something above it suspends, and Next
14
+ * fails the build for a page that lets it. The boundary is here so a host does not have to know.
15
+ */
16
+ function PageViews() {
11
17
  const pathname = usePathname();
12
- useWebAnalytics(pathname);
18
+ const searchParams = useSearchParams();
19
+ useWebAnalytics(pathname, searchParams.toString());
20
+ return null;
21
+ }
22
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, redditPixelId, linkedInPartnerId, uetTagId, facebookAppId, reportWebVitals = true }) {
13
23
  useOutboundClickAnalytics();
14
24
  useReportWebVitals((metric) => {
15
25
  if (!reportWebVitals) return;
@@ -25,6 +35,10 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, reddi
25
35
  track(metric.name, properties);
26
36
  });
27
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
38
+ /* @__PURE__ */ jsx(Suspense, {
39
+ fallback: null,
40
+ children: /* @__PURE__ */ jsx(PageViews, {})
41
+ }),
28
42
  facebookAppId && /* @__PURE__ */ jsx("meta", {
29
43
  property: "fb:app_id",
30
44
  content: facebookAppId
@@ -108,6 +122,28 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, hotjarId, reddi
108
122
  s.parentNode.insertBefore(b, s);
109
123
  })(window.lintrk);
110
124
  ` }
125
+ }),
126
+ uetTagId && /* @__PURE__ */ jsx(Script, {
127
+ strategy: "afterInteractive",
128
+ id: "uet-tag",
129
+ dangerouslySetInnerHTML: { __html: `
130
+ (function (w, d, t, u, o) {
131
+ w[u] = w[u] || [], o.ts = (new Date).getTime();
132
+ var n = d.createElement(t);
133
+ n.src = "https://bat.bing.net/bat.js?ti=" + o.ti + ("uetq" != u ? "&q=" + u : ""),
134
+ n.async = 1, n.onload = n.onreadystatechange = function() {
135
+ var s = this.readyState;
136
+ s && "loaded" !== s && "complete" !== s ||
137
+ (o.q = w[u], w[u] = new UET(o), w[u].push("pageLoad"),
138
+ n.onload = n.onreadystatechange = null)
139
+ };
140
+ var i = d.getElementsByTagName(t)[0];
141
+ i.parentNode.insertBefore(n, i);
142
+ })(window, document, "script", "uetq", {
143
+ ti: "${uetTagId}",
144
+ enableAutoSpaTracking: true
145
+ });
146
+ ` }
111
147
  }),
112
148
  hotjarId && /* @__PURE__ */ jsx(Script, {
113
149
  id: "hotjar",
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/next/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname } from 'next/navigation';\nimport Script from 'next/script';\nimport { useReportWebVitals } from 'next/web-vitals';\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 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 hotjarId,\n redditPixelId,\n linkedInPartnerId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const pathname = usePathname();\n useWebAnalytics(pathname);\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 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 {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":";;;;;;;;;AA0BA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,UACA,eACA,mBACA,eACA,kBAAkB,QACV;CACR,MAAM,WAAW,YAAY;CAC7B,gBAAgB,QAAQ;CACxB,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,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,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 { 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"}
@@ -6,9 +6,9 @@ const require_hooks_use_web_analytics = require("../hooks/use-web-analytics.cjs"
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
7
  let react_router = require("react-router");
8
8
  //#region src/react-router/index.tsx
9
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, hotjarId, facebookAppId, reportWebVitals = true }) {
10
- const { pathname } = (0, react_router.useLocation)();
11
- require_hooks_use_web_analytics.useWebAnalytics(pathname);
9
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals = true }) {
10
+ const { pathname, search } = (0, react_router.useLocation)();
11
+ require_hooks_use_web_analytics.useWebAnalytics(pathname, search);
12
12
  require_hooks_use_outbound_click_analytics.useOutboundClickAnalytics();
13
13
  require_hooks_use_report_web_vitals.useReportWebVitals((metric) => {
14
14
  if (!reportWebVitals) return;
@@ -108,6 +108,28 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId,
108
108
  b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
109
109
  s.parentNode.insertBefore(b, s);
110
110
  })(window.lintrk);
111
+ ` }
112
+ }),
113
+ uetTagId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("script", {
114
+ async: true,
115
+ id: "uet-tag",
116
+ dangerouslySetInnerHTML: { __html: `
117
+ (function (w, d, t, u, o) {
118
+ w[u] = w[u] || [], o.ts = (new Date).getTime();
119
+ var n = d.createElement(t);
120
+ n.src = "https://bat.bing.net/bat.js?ti=" + o.ti + ("uetq" != u ? "&q=" + u : ""),
121
+ n.async = 1, n.onload = n.onreadystatechange = function() {
122
+ var s = this.readyState;
123
+ s && "loaded" !== s && "complete" !== s ||
124
+ (o.q = w[u], w[u] = new UET(o), w[u].push("pageLoad"),
125
+ n.onload = n.onreadystatechange = null)
126
+ };
127
+ var i = d.getElementsByTagName(t)[0];
128
+ i.parentNode.insertBefore(n, i);
129
+ })(window, document, "script", "uetq", {
130
+ ti: "${uetTagId}",
131
+ enableAutoSpaTracking: true
132
+ });
111
133
  ` }
112
134
  }),
113
135
  hotjarId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("script", {
@@ -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 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 hotjarId,\n facebookAppId,\n reportWebVitals = true,\n}: Props) {\n const { pathname } = useLocation();\n useWebAnalytics(pathname);\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 {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":";;;;;;;;AAuBA,SAAgB,UAAU,EACxB,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,kBAAkB,QACV;CACR,MAAM,EAAE,cAAA,GAAaA,aAAAA,YAAAA,CAAY;CACjC,gCAAA,gBAAgB,QAAQ;CACxB,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;;;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 { 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"}
@@ -9,13 +9,15 @@ interface Props {
9
9
  metaPixelId?: PixelId;
10
10
  redditPixelId?: PixelId$1;
11
11
  linkedInPartnerId?: `${number}`;
12
+ /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
13
+ uetTagId?: `${number}`;
12
14
  hotjarId?: `${number}`;
13
15
  facebookAppId?: string;
14
16
  nonce?: string;
15
17
  debugMode?: boolean;
16
18
  reportWebVitals?: boolean;
17
19
  }
18
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
20
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
19
21
  //#endregion
20
22
  export { Analytics };
21
23
  //# 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;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,mBACC,wBAAK,IAAA"}
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"}
@@ -9,13 +9,15 @@ interface Props {
9
9
  metaPixelId?: PixelId;
10
10
  redditPixelId?: PixelId$1;
11
11
  linkedInPartnerId?: `${number}`;
12
+ /** Microsoft Advertising UET tag id. The tag reports page loads itself (`enableAutoSpaTracking`). */
13
+ uetTagId?: `${number}`;
12
14
  hotjarId?: `${number}`;
13
15
  facebookAppId?: string;
14
16
  nonce?: string;
15
17
  debugMode?: boolean;
16
18
  reportWebVitals?: boolean;
17
19
  }
18
- declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
20
+ declare function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals }: Props): import("react").JSX.Element;
19
21
  //#endregion
20
22
  export { Analytics };
21
23
  //# 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;EACA;EACA;EACA;EACA;EACA;;iBAGc,YACd,MACA,OACA,OACA,WACA,aACA,eACA,mBACA,UACA,eACA,mBACC,wBAAK,IAAA"}
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"}
@@ -5,9 +5,9 @@ import { useWebAnalytics } from "../hooks/use-web-analytics.mjs";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useLocation } from "react-router";
7
7
  //#region src/react-router/index.tsx
8
- function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, hotjarId, facebookAppId, reportWebVitals = true }) {
9
- const { pathname } = useLocation();
10
- useWebAnalytics(pathname);
8
+ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId, linkedInPartnerId, uetTagId, hotjarId, facebookAppId, reportWebVitals = true }) {
9
+ const { pathname, search } = useLocation();
10
+ useWebAnalytics(pathname, search);
11
11
  useOutboundClickAnalytics();
12
12
  useReportWebVitals((metric) => {
13
13
  if (!reportWebVitals) return;
@@ -107,6 +107,28 @@ function Analytics({ gaId, gaSrc, nonce, debugMode, metaPixelId, redditPixelId,
107
107
  b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
108
108
  s.parentNode.insertBefore(b, s);
109
109
  })(window.lintrk);
110
+ ` }
111
+ }),
112
+ uetTagId && /* @__PURE__ */ jsx("script", {
113
+ async: true,
114
+ id: "uet-tag",
115
+ dangerouslySetInnerHTML: { __html: `
116
+ (function (w, d, t, u, o) {
117
+ w[u] = w[u] || [], o.ts = (new Date).getTime();
118
+ var n = d.createElement(t);
119
+ n.src = "https://bat.bing.net/bat.js?ti=" + o.ti + ("uetq" != u ? "&q=" + u : ""),
120
+ n.async = 1, n.onload = n.onreadystatechange = function() {
121
+ var s = this.readyState;
122
+ s && "loaded" !== s && "complete" !== s ||
123
+ (o.q = w[u], w[u] = new UET(o), w[u].push("pageLoad"),
124
+ n.onload = n.onreadystatechange = null)
125
+ };
126
+ var i = d.getElementsByTagName(t)[0];
127
+ i.parentNode.insertBefore(n, i);
128
+ })(window, document, "script", "uetq", {
129
+ ti: "${uetTagId}",
130
+ enableAutoSpaTracking: true
131
+ });
110
132
  ` }
111
133
  }),
112
134
  hotjarId && /* @__PURE__ */ jsx("script", {