@aranova/tracking-next 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,12 +23,32 @@ export const config = {
23
23
  };
24
24
  ```
25
25
 
26
+ **Next 16:** the `middleware` file convention is deprecated in favor of `proxy`.
27
+ `createTrackingMiddleware()` returns a convention-agnostic handler, so no code change is
28
+ needed — just rename the file to `proxy.ts` and keep the same default export and `config`:
29
+
30
+ ```ts
31
+ // proxy.ts
32
+ import { createTrackingMiddleware } from "@aranova/tracking-next/middleware";
33
+
34
+ export default createTrackingMiddleware();
35
+
36
+ export const config = {
37
+ matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
38
+ };
39
+ ```
40
+
41
+ `middleware.ts` still works during the transition; use `proxy.ts` on Next 16+ to silence the
42
+ deprecation warning.
43
+
26
44
  ## Provider
27
45
 
28
46
  Create one shared tracking module and use its scoped exports throughout your app.
29
47
 
30
48
  ```ts
31
49
  // lib/tracking.ts
50
+ "use client";
51
+
32
52
  import { createTracking } from "@aranova/tracking-next";
33
53
 
34
54
  export const { TrackingProvider, useTracking } = createTracking({
@@ -75,6 +95,15 @@ export default function RootLayout({ children }: { children: React.ReactNode })
75
95
  }
76
96
  ```
77
97
 
98
+ `lib/tracking.ts` needs the `"use client"` directive above because `createTracking()`
99
+ creates React context — the module that calls it is a Client Component. Your root layout
100
+ stays a Server Component and just renders the client `<TrackingProvider>`.
101
+
102
+ **No consumer `<Suspense>` boundary is required.** The provider reads `useSearchParams()`
103
+ only inside its own internal `<Suspense>` boundary, so it never opts the enclosing route out
104
+ of static prerendering. A fully static page (including one with `export const dynamic = 'error'`)
105
+ builds cleanly and stays `○ (Static)` with `<TrackingProvider>` in the root layout.
106
+
78
107
  Tracking is on by default (consent v2, opt-out model) — no banner. Add a footer
79
108
  "cookie preferences" control built on `useCookiePreferences()` (see **Consent** below)
80
109
  and disclose the tracking + opt-out in the site's privacy policy.
package/dist/index.js CHANGED
@@ -1750,6 +1750,7 @@ function attachFormStart(client, config) {
1750
1750
  }
1751
1751
 
1752
1752
  // ../tracking-core/src/triggers/page-exit.ts
1753
+ var MIN_SEGMENT_MS = 50;
1753
1754
  function attachPageExit(client) {
1754
1755
  if (typeof window === "undefined" || typeof document === "undefined") {
1755
1756
  return () => {
@@ -1787,7 +1788,7 @@ function attachPageExit(client) {
1787
1788
  }
1788
1789
  function emitSegment(path, flush) {
1789
1790
  const dwell = settledDwellMs();
1790
- if (dwell === 0) return;
1791
+ if (dwell < MIN_SEGMENT_MS) return;
1791
1792
  client.trackEvent({
1792
1793
  eventType: "page_exit",
1793
1794
  metadata: {
@@ -1802,7 +1803,7 @@ function attachPageExit(client) {
1802
1803
  client.flushBeacon();
1803
1804
  }
1804
1805
  accumulatedMs = 0;
1805
- activeSince = document.visibilityState === "visible" ? Date.now() : null;
1806
+ activeSince = null;
1806
1807
  }
1807
1808
  function onNavigate() {
1808
1809
  const newPath = window.location.pathname;
@@ -2604,7 +2605,7 @@ function GoogleAdsTracking(props) {
2604
2605
  var import_navigation = require("next/navigation");
2605
2606
 
2606
2607
  // package.json
2607
- var version = "0.16.0";
2608
+ var version = "0.16.2";
2608
2609
 
2609
2610
  // src/factory.tsx
2610
2611
  var import_react4 = require("react");
@@ -2697,6 +2698,14 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
2697
2698
 
2698
2699
  // src/factory.tsx
2699
2700
  var import_jsx_runtime5 = require("react/jsx-runtime");
2701
+ function PageViewTracker({ fire }) {
2702
+ const pathname = (0, import_navigation.usePathname)();
2703
+ const searchParams = (0, import_navigation.useSearchParams)();
2704
+ (0, import_react4.useEffect)(() => {
2705
+ fire();
2706
+ }, [pathname, searchParams, fire]);
2707
+ return null;
2708
+ }
2700
2709
  function createTracking(options) {
2701
2710
  const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
2702
2711
  if (!apiKey || !endpoint) {
@@ -2723,7 +2732,6 @@ function createTracking(options) {
2723
2732
  const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
2724
2733
  function TrackingProvider({ children }) {
2725
2734
  const pathname = (0, import_navigation.usePathname)();
2726
- const searchParams = (0, import_navigation.useSearchParams)();
2727
2735
  const client = (0, import_react4.useMemo)(
2728
2736
  () => createTypedClient(
2729
2737
  getOrCreateTrackingClient({
@@ -2753,7 +2761,7 @@ function createTracking(options) {
2753
2761
  const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
2754
2762
  return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
2755
2763
  }, [conversionStore]);
2756
- (0, import_react4.useEffect)(() => {
2764
+ const firePageView = (0, import_react4.useCallback)(() => {
2757
2765
  const rawClient = getOrCreateTrackingClient({
2758
2766
  apiKey,
2759
2767
  endpoint,
@@ -2765,7 +2773,7 @@ function createTracking(options) {
2765
2773
  debug
2766
2774
  });
2767
2775
  fireManualPageView(wrapClient(rawClient));
2768
- }, [pathname, searchParams]);
2776
+ }, [wrapClient]);
2769
2777
  const firedPagesRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
2770
2778
  (0, import_react4.useEffect)(() => {
2771
2779
  if (!specificPageVisitConfig || pathname === null) return;
@@ -2904,7 +2912,10 @@ function createTracking(options) {
2904
2912
  }
2905
2913
  };
2906
2914
  }, []);
2907
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children }) });
2915
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(TrackingContext.Provider, { value: client, children: [
2916
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react4.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageViewTracker, { fire: firePageView }) }),
2917
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children })
2918
+ ] });
2908
2919
  }
2909
2920
  function useTracking() {
2910
2921
  const client = (0, import_react4.useContext)(TrackingContext);