@productbet/tracker-react 0.1.0 → 0.1.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 +119 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @productbet/tracker-react
|
|
2
|
+
|
|
3
|
+
React integration for [ProductBet](https://productbet.io) behavioral analytics. Provides a context provider and hooks for session recording, event tracking, and user identification.
|
|
4
|
+
|
|
5
|
+
> For **Next.js App Router** projects, use **[@productbet/tracker-next](https://www.npmjs.com/package/@productbet/tracker-next)** instead, which adds automatic route tracking.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @productbet/tracker-react
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
Wrap your app with `ProductBetProvider`:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { ProductBetProvider } from "@productbet/tracker-react"
|
|
19
|
+
|
|
20
|
+
function App() {
|
|
21
|
+
return (
|
|
22
|
+
<ProductBetProvider apiKey="pb_live_xxxx">
|
|
23
|
+
<YourApp />
|
|
24
|
+
</ProductBetProvider>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
That's it. The SDK will automatically track clicks, form interactions, scroll depth, navigation, console errors, and network failures.
|
|
30
|
+
|
|
31
|
+
## Hooks
|
|
32
|
+
|
|
33
|
+
### `useIdentify`
|
|
34
|
+
|
|
35
|
+
Identify the current user. Call this once the user is authenticated.
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { useIdentify } from "@productbet/tracker-react"
|
|
39
|
+
|
|
40
|
+
function Dashboard({ user }) {
|
|
41
|
+
useIdentify(user.id, { plan: user.plan, company: user.company })
|
|
42
|
+
|
|
43
|
+
return <div>...</div>
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### `useTrackEvent`
|
|
48
|
+
|
|
49
|
+
Track custom events.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { useTrackEvent } from "@productbet/tracker-react"
|
|
53
|
+
|
|
54
|
+
function ExportButton() {
|
|
55
|
+
const track = useTrackEvent()
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<button onClick={() => track("export_clicked", { format: "csv" })}>
|
|
59
|
+
Export
|
|
60
|
+
</button>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `usePageView`
|
|
66
|
+
|
|
67
|
+
Manually track page views (useful for SPAs without Next.js).
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { usePageView } from "@productbet/tracker-react"
|
|
71
|
+
import { useLocation } from "react-router-dom"
|
|
72
|
+
|
|
73
|
+
function PageTracker() {
|
|
74
|
+
const location = useLocation()
|
|
75
|
+
usePageView(location.pathname)
|
|
76
|
+
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `useTracker`
|
|
82
|
+
|
|
83
|
+
Access the underlying tracker instance for advanced use cases.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { useTracker } from "@productbet/tracker-react"
|
|
87
|
+
|
|
88
|
+
function Component() {
|
|
89
|
+
const tracker = useTracker()
|
|
90
|
+
|
|
91
|
+
// tracker.getSessionId()
|
|
92
|
+
// tracker.track(...)
|
|
93
|
+
// tracker.identify(...)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
Pass any option as a prop to `ProductBetProvider`:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<ProductBetProvider
|
|
103
|
+
apiKey="pb_live_xxxx"
|
|
104
|
+
enableSessionRecording={true}
|
|
105
|
+
enableAutoTracking={true}
|
|
106
|
+
enableConsoleTracking={true}
|
|
107
|
+
enableNetworkTracking={true}
|
|
108
|
+
debug={false}
|
|
109
|
+
redaction={{ mode: "privacy-first", unredactFields: ["search"] }}
|
|
110
|
+
>
|
|
111
|
+
<App />
|
|
112
|
+
</ProductBetProvider>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
See [@productbet/tracker-core](https://www.npmjs.com/package/@productbet/tracker-core) for the full list of options.
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ProductBetProvider, ProductBetContext } from "./provider";
|
|
2
2
|
export type { ProductBetProviderProps } from "./provider";
|
|
3
3
|
export { useTracker, useIdentify, useTrackEvent, usePageView } from "./hooks";
|
|
4
|
-
export
|
|
4
|
+
export { ProductBetTracker } from "@productbet/tracker-core";
|
|
5
|
+
export type { TrackerOptions, AutoTrackingOptions, RedactionOptions, UserProperties, TrackedEvent, EventType, } from "@productbet/tracker-core";
|
package/dist/index.js
CHANGED
|
@@ -60,6 +60,10 @@ function usePageView(pathname) {
|
|
|
60
60
|
}, [tracker, pathname]);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
Object.defineProperty(exports, "ProductBetTracker", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
get: function () { return trackerCore.ProductBetTracker; }
|
|
66
|
+
});
|
|
63
67
|
exports.ProductBetContext = ProductBetContext;
|
|
64
68
|
exports.ProductBetProvider = ProductBetProvider;
|
|
65
69
|
exports.useIdentify = useIdentify;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["createContext","useRef","ProductBetTracker","useEffect","_jsx","useContext"],"mappings":";;;;;;MAWa,iBAAiB,GAAGA,mBAAa,CAA2B,IAAI;AAOvE,SAAU,kBAAkB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,OAAO,EACY,EAAA;AACtB,IAAA,MAAM,UAAU,GAAGC,YAAM,CAA2B,IAAI,CAAC;IAEzD,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACtD,UAAU,CAAC,OAAO,GAAGC,6BAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE;IAEAC,eAAS,CAAC,MAAK;AACX,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;AAClC,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,OAAO,CAAC,KAAK,EAAE;AAEf,QAAA,OAAO,MAAK;YACR,OAAO,CAAC,IAAI,EAAE;AAClB,QAAA,CAAC;IACL,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACIC,cAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAA,QAAA,EAChD,QAAQ,EAAA,CACgB;AAErC;;SCzCgB,UAAU,GAAA;AACtB,IAAA,OAAOC,gBAAU,CAAC,iBAAiB,CAAC;AACxC;AAEM,SAAU,WAAW,CACvB,MAAiC,EACjC,UAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,aAAa,GAAGJ,YAAM,CAA4B,IAAI,CAAC;IAE7DE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE;AACzB,QAAA,IAAI,MAAM,KAAK,aAAa,CAAC,OAAO;YAAE;AAEtC,QAAA,aAAa,CAAC,OAAO,GAAG,MAAM;AAC9B,QAAA,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrC;SAEgB,aAAa,GAAA;AAIzB,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAE5B,IAAA,OAAO,CAAC,SAAiB,EAAE,UAAoC,KAAI;AAC/D,QAAA,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;AACzC,IAAA,CAAC;AACL;AAEM,SAAU,WAAW,CAAC,QAAiB,EAAA;AACzC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,WAAW,GAAGF,YAAM,CAAqB,SAAS,CAAC;IAEzDE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE;AAC3B,QAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO;YAAE;AAEtC,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC9B,QAAA,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE;AACxB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;AACrE,YAAA,KAAK,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS;AACtE,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3B
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["createContext","useRef","ProductBetTracker","useEffect","_jsx","useContext"],"mappings":";;;;;;MAWa,iBAAiB,GAAGA,mBAAa,CAA2B,IAAI;AAOvE,SAAU,kBAAkB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,OAAO,EACY,EAAA;AACtB,IAAA,MAAM,UAAU,GAAGC,YAAM,CAA2B,IAAI,CAAC;IAEzD,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACtD,UAAU,CAAC,OAAO,GAAGC,6BAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE;IAEAC,eAAS,CAAC,MAAK;AACX,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;AAClC,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,OAAO,CAAC,KAAK,EAAE;AAEf,QAAA,OAAO,MAAK;YACR,OAAO,CAAC,IAAI,EAAE;AAClB,QAAA,CAAC;IACL,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACIC,cAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAA,QAAA,EAChD,QAAQ,EAAA,CACgB;AAErC;;SCzCgB,UAAU,GAAA;AACtB,IAAA,OAAOC,gBAAU,CAAC,iBAAiB,CAAC;AACxC;AAEM,SAAU,WAAW,CACvB,MAAiC,EACjC,UAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,aAAa,GAAGJ,YAAM,CAA4B,IAAI,CAAC;IAE7DE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE;AACzB,QAAA,IAAI,MAAM,KAAK,aAAa,CAAC,OAAO;YAAE;AAEtC,QAAA,aAAa,CAAC,OAAO,GAAG,MAAM;AAC9B,QAAA,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrC;SAEgB,aAAa,GAAA;AAIzB,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAE5B,IAAA,OAAO,CAAC,SAAiB,EAAE,UAAoC,KAAI;AAC/D,QAAA,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;AACzC,IAAA,CAAC;AACL;AAEM,SAAU,WAAW,CAAC,QAAiB,EAAA;AACzC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,WAAW,GAAGF,YAAM,CAAqB,SAAS,CAAC;IAEzDE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE;AAC3B,QAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO;YAAE;AAEtC,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC9B,QAAA,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE;AACxB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;AACrE,YAAA,KAAK,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS;AACtE,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3B;;;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { createContext, useRef, useEffect, useContext } from 'react';
|
|
3
3
|
import { ProductBetTracker } from '@productbet/tracker-core';
|
|
4
|
+
export { ProductBetTracker } from '@productbet/tracker-core';
|
|
4
5
|
|
|
5
6
|
const ProductBetContext = createContext(null);
|
|
6
7
|
function ProductBetProvider({ apiKey, children, ...options }) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["_jsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["_jsx"],"mappings":";;;;;MAWa,iBAAiB,GAAG,aAAa,CAA2B,IAAI;AAOvE,SAAU,kBAAkB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,OAAO,EACY,EAAA;AACtB,IAAA,MAAM,UAAU,GAAG,MAAM,CAA2B,IAAI,CAAC;IAEzD,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACtD,UAAU,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE;IAEA,SAAS,CAAC,MAAK;AACX,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;AAClC,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,OAAO,CAAC,KAAK,EAAE;AAEf,QAAA,OAAO,MAAK;YACR,OAAO,CAAC,IAAI,EAAE;AAClB,QAAA,CAAC;IACL,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACIA,GAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAA,QAAA,EAChD,QAAQ,EAAA,CACgB;AAErC;;SCzCgB,UAAU,GAAA;AACtB,IAAA,OAAO,UAAU,CAAC,iBAAiB,CAAC;AACxC;AAEM,SAAU,WAAW,CACvB,MAAiC,EACjC,UAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,aAAa,GAAG,MAAM,CAA4B,IAAI,CAAC;IAE7D,SAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE;AACzB,QAAA,IAAI,MAAM,KAAK,aAAa,CAAC,OAAO;YAAE;AAEtC,QAAA,aAAa,CAAC,OAAO,GAAG,MAAM;AAC9B,QAAA,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrC;SAEgB,aAAa,GAAA;AAIzB,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAE5B,IAAA,OAAO,CAAC,SAAiB,EAAE,UAAoC,KAAI;AAC/D,QAAA,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;AACzC,IAAA,CAAC;AACL;AAEM,SAAU,WAAW,CAAC,QAAiB,EAAA;AACzC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,WAAW,GAAG,MAAM,CAAqB,SAAS,CAAC;IAEzD,SAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE;AAC3B,QAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO;YAAE;AAEtC,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC9B,QAAA,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE;AACxB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;AACrE,YAAA,KAAK,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS;AACtE,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3B;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productbet/tracker-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "React integration for ProductBet behavioral analytics SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@productbet/tracker-core": "0.1.
|
|
19
|
+
"@productbet/tracker-core": "0.1.1"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"react": ">=18.0.0",
|