@aranova/tracking-next 0.16.0 → 0.16.1

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
@@ -2604,7 +2604,7 @@ function GoogleAdsTracking(props) {
2604
2604
  var import_navigation = require("next/navigation");
2605
2605
 
2606
2606
  // package.json
2607
- var version = "0.16.0";
2607
+ var version = "0.16.1";
2608
2608
 
2609
2609
  // src/factory.tsx
2610
2610
  var import_react4 = require("react");
@@ -2697,6 +2697,14 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
2697
2697
 
2698
2698
  // src/factory.tsx
2699
2699
  var import_jsx_runtime5 = require("react/jsx-runtime");
2700
+ function PageViewTracker({ fire }) {
2701
+ const pathname = (0, import_navigation.usePathname)();
2702
+ const searchParams = (0, import_navigation.useSearchParams)();
2703
+ (0, import_react4.useEffect)(() => {
2704
+ fire();
2705
+ }, [pathname, searchParams, fire]);
2706
+ return null;
2707
+ }
2700
2708
  function createTracking(options) {
2701
2709
  const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
2702
2710
  if (!apiKey || !endpoint) {
@@ -2723,7 +2731,6 @@ function createTracking(options) {
2723
2731
  const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
2724
2732
  function TrackingProvider({ children }) {
2725
2733
  const pathname = (0, import_navigation.usePathname)();
2726
- const searchParams = (0, import_navigation.useSearchParams)();
2727
2734
  const client = (0, import_react4.useMemo)(
2728
2735
  () => createTypedClient(
2729
2736
  getOrCreateTrackingClient({
@@ -2753,7 +2760,7 @@ function createTracking(options) {
2753
2760
  const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
2754
2761
  return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
2755
2762
  }, [conversionStore]);
2756
- (0, import_react4.useEffect)(() => {
2763
+ const firePageView = (0, import_react4.useCallback)(() => {
2757
2764
  const rawClient = getOrCreateTrackingClient({
2758
2765
  apiKey,
2759
2766
  endpoint,
@@ -2765,7 +2772,7 @@ function createTracking(options) {
2765
2772
  debug
2766
2773
  });
2767
2774
  fireManualPageView(wrapClient(rawClient));
2768
- }, [pathname, searchParams]);
2775
+ }, [wrapClient]);
2769
2776
  const firedPagesRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
2770
2777
  (0, import_react4.useEffect)(() => {
2771
2778
  if (!specificPageVisitConfig || pathname === null) return;
@@ -2904,7 +2911,10 @@ function createTracking(options) {
2904
2911
  }
2905
2912
  };
2906
2913
  }, []);
2907
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children }) });
2914
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(TrackingContext.Provider, { value: client, children: [
2915
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react4.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageViewTracker, { fire: firePageView }) }),
2916
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children })
2917
+ ] });
2908
2918
  }
2909
2919
  function useTracking() {
2910
2920
  const client = (0, import_react4.useContext)(TrackingContext);