@litemetrics/react 0.1.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.
- package/dist/index.cjs +110 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +67 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
LitemetricsProvider: () => LitemetricsProvider,
|
|
24
|
+
useLitemetrics: () => useLitemetrics,
|
|
25
|
+
usePageView: () => usePageView,
|
|
26
|
+
useTrackEvent: () => useTrackEvent
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
|
|
30
|
+
// src/context.tsx
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
var import_tracker = require("@litemetrics/tracker");
|
|
33
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
34
|
+
var LitemetricsContext = (0, import_react.createContext)(null);
|
|
35
|
+
function LitemetricsProvider({
|
|
36
|
+
children,
|
|
37
|
+
autoPageView = true,
|
|
38
|
+
...config
|
|
39
|
+
}) {
|
|
40
|
+
const trackerRef = (0, import_react.useRef)(null);
|
|
41
|
+
if (!trackerRef.current) {
|
|
42
|
+
trackerRef.current = (0, import_tracker.createTracker)({
|
|
43
|
+
...config,
|
|
44
|
+
// Disable built-in auto tracking; we'll handle it via hooks for SPA
|
|
45
|
+
autoTrack: autoPageView && !config.autoSpa,
|
|
46
|
+
autoSpa: false
|
|
47
|
+
// We handle SPA tracking via usePageView hook
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
(0, import_react.useEffect)(() => {
|
|
51
|
+
return () => {
|
|
52
|
+
trackerRef.current?.destroy();
|
|
53
|
+
};
|
|
54
|
+
}, []);
|
|
55
|
+
const value = (0, import_react.useMemo)(
|
|
56
|
+
() => ({
|
|
57
|
+
tracker: trackerRef.current,
|
|
58
|
+
siteId: config.siteId
|
|
59
|
+
}),
|
|
60
|
+
[config.siteId]
|
|
61
|
+
);
|
|
62
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LitemetricsContext.Provider, { value, children });
|
|
63
|
+
}
|
|
64
|
+
function useLitemetricsContext() {
|
|
65
|
+
const ctx = (0, import_react.useContext)(LitemetricsContext);
|
|
66
|
+
if (!ctx) {
|
|
67
|
+
throw new Error("useLitemetrics must be used within <LitemetricsProvider>");
|
|
68
|
+
}
|
|
69
|
+
return ctx;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/hooks.ts
|
|
73
|
+
var import_react2 = require("react");
|
|
74
|
+
function useLitemetrics() {
|
|
75
|
+
const { tracker } = useLitemetricsContext();
|
|
76
|
+
return {
|
|
77
|
+
track: tracker.track.bind(tracker),
|
|
78
|
+
identify: tracker.identify.bind(tracker),
|
|
79
|
+
page: tracker.page.bind(tracker),
|
|
80
|
+
reset: tracker.reset.bind(tracker),
|
|
81
|
+
opt_out: tracker.opt_out.bind(tracker),
|
|
82
|
+
opt_in: tracker.opt_in.bind(tracker)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function usePageView(pathname) {
|
|
86
|
+
const { tracker } = useLitemetricsContext();
|
|
87
|
+
const isFirst = (0, import_react2.useRef)(true);
|
|
88
|
+
(0, import_react2.useEffect)(() => {
|
|
89
|
+
if (isFirst.current) {
|
|
90
|
+
isFirst.current = false;
|
|
91
|
+
tracker.page();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
tracker.page();
|
|
95
|
+
}, [pathname, tracker]);
|
|
96
|
+
}
|
|
97
|
+
function useTrackEvent(name, properties) {
|
|
98
|
+
const { tracker } = useLitemetricsContext();
|
|
99
|
+
(0, import_react2.useEffect)(() => {
|
|
100
|
+
tracker.track(name, properties);
|
|
101
|
+
}, [name]);
|
|
102
|
+
}
|
|
103
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
104
|
+
0 && (module.exports = {
|
|
105
|
+
LitemetricsProvider,
|
|
106
|
+
useLitemetrics,
|
|
107
|
+
usePageView,
|
|
108
|
+
useTrackEvent
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.tsx","../src/hooks.ts"],"sourcesContent":["export { LitemetricsProvider } from './context';\nexport type { LitemetricsProviderProps } from './context';\nexport { useLitemetrics, usePageView, useTrackEvent } from './hooks';\n","import { createContext, useContext, useEffect, useRef, useMemo } from 'react';\nimport type { LitemetricsInstance, TrackerConfig } from '@litemetrics/tracker';\nimport { createTracker } from '@litemetrics/tracker';\n\ninterface LitemetricsContextValue {\n tracker: LitemetricsInstance;\n siteId: string;\n}\n\nconst LitemetricsContext = createContext<LitemetricsContextValue | null>(null);\n\nexport interface LitemetricsProviderProps extends Omit<TrackerConfig, 'autoTrack'> {\n children: React.ReactNode;\n autoPageView?: boolean;\n}\n\nexport function LitemetricsProvider({\n children,\n autoPageView = true,\n ...config\n}: LitemetricsProviderProps) {\n const trackerRef = useRef<LitemetricsInstance | null>(null);\n\n if (!trackerRef.current) {\n trackerRef.current = createTracker({\n ...config,\n // Disable built-in auto tracking; we'll handle it via hooks for SPA\n autoTrack: autoPageView && !config.autoSpa,\n autoSpa: false, // We handle SPA tracking via usePageView hook\n });\n }\n\n useEffect(() => {\n return () => {\n trackerRef.current?.destroy();\n };\n }, []);\n\n const value = useMemo<LitemetricsContextValue>(\n () => ({\n tracker: trackerRef.current!,\n siteId: config.siteId,\n }),\n [config.siteId],\n );\n\n return (\n <LitemetricsContext.Provider value={value}>\n {children}\n </LitemetricsContext.Provider>\n );\n}\n\nexport function useLitemetricsContext(): LitemetricsContextValue {\n const ctx = useContext(LitemetricsContext);\n if (!ctx) {\n throw new Error('useLitemetrics must be used within <LitemetricsProvider>');\n }\n return ctx;\n}\n","import { useEffect, useRef } from 'react';\nimport { useLitemetricsContext } from './context';\n\n/**\n * Access the Litemetrics tracker instance.\n *\n * @example\n * ```tsx\n * function Button() {\n * const { track, identify } = useLitemetrics();\n * return <button onClick={() => track('click', { id: 'cta' })}>Click</button>;\n * }\n * ```\n */\nexport function useLitemetrics() {\n const { tracker } = useLitemetricsContext();\n\n return {\n track: tracker.track.bind(tracker),\n identify: tracker.identify.bind(tracker),\n page: tracker.page.bind(tracker),\n reset: tracker.reset.bind(tracker),\n opt_out: tracker.opt_out.bind(tracker),\n opt_in: tracker.opt_in.bind(tracker),\n };\n}\n\n/**\n * Automatically track page views when the URL changes.\n * Works with React Router, TanStack Router, or any router that updates `location`.\n *\n * @param deps - Dependencies to trigger page view (e.g., pathname from router).\n * If not provided, uses `window.location.href`.\n *\n * @example\n * ```tsx\n * // With React Router v6+\n * import { useLocation } from 'react-router-dom';\n * function PageTracker() {\n * const { pathname } = useLocation();\n * usePageView(pathname);\n * return null;\n * }\n *\n * // Without router (fallback to window.location)\n * function App() {\n * usePageView();\n * return <div>...</div>;\n * }\n * ```\n */\nexport function usePageView(pathname?: string) {\n const { tracker } = useLitemetricsContext();\n const isFirst = useRef(true);\n\n useEffect(() => {\n // Skip first render if autoTrack already fired\n if (isFirst.current) {\n isFirst.current = false;\n // Track initial page view\n tracker.page();\n return;\n }\n\n // Track subsequent navigations\n tracker.page();\n }, [pathname, tracker]);\n}\n\n/**\n * Track a custom event when the component mounts.\n *\n * @example\n * ```tsx\n * function PricingPage() {\n * useTrackEvent('page_section_viewed', { section: 'pricing' });\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useTrackEvent(name: string, properties?: Record<string, unknown>) {\n const { tracker } = useLitemetricsContext();\n\n useEffect(() => {\n tracker.track(name, properties);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [name]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAsE;AAEtE,qBAA8B;AA6C1B;AAtCJ,IAAM,yBAAqB,4BAA8C,IAAI;AAOtE,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,GAA6B;AAC3B,QAAM,iBAAa,qBAAmC,IAAI;AAE1D,MAAI,CAAC,WAAW,SAAS;AACvB,eAAW,cAAU,8BAAc;AAAA,MACjC,GAAG;AAAA;AAAA,MAEH,WAAW,gBAAgB,CAAC,OAAO;AAAA,MACnC,SAAS;AAAA;AAAA,IACX,CAAC;AAAA,EACH;AAEA,8BAAU,MAAM;AACd,WAAO,MAAM;AACX,iBAAW,SAAS,QAAQ;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAQ;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,WAAW;AAAA,MACpB,QAAQ,OAAO;AAAA,IACjB;AAAA,IACA,CAAC,OAAO,MAAM;AAAA,EAChB;AAEA,SACE,4CAAC,mBAAmB,UAAnB,EAA4B,OAC1B,UACH;AAEJ;AAEO,SAAS,wBAAiD;AAC/D,QAAM,UAAM,yBAAW,kBAAkB;AACzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;;;AC3DA,IAAAA,gBAAkC;AAc3B,SAAS,iBAAiB;AAC/B,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAE1C,SAAO;AAAA,IACL,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,IACjC,UAAU,QAAQ,SAAS,KAAK,OAAO;AAAA,IACvC,MAAM,QAAQ,KAAK,KAAK,OAAO;AAAA,IAC/B,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,IACjC,SAAS,QAAQ,QAAQ,KAAK,OAAO;AAAA,IACrC,QAAQ,QAAQ,OAAO,KAAK,OAAO;AAAA,EACrC;AACF;AA0BO,SAAS,YAAY,UAAmB;AAC7C,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAC1C,QAAM,cAAU,sBAAO,IAAI;AAE3B,+BAAU,MAAM;AAEd,QAAI,QAAQ,SAAS;AACnB,cAAQ,UAAU;AAElB,cAAQ,KAAK;AACb;AAAA,IACF;AAGA,YAAQ,KAAK;AAAA,EACf,GAAG,CAAC,UAAU,OAAO,CAAC;AACxB;AAaO,SAAS,cAAc,MAAc,YAAsC;AAChF,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAE1C,+BAAU,MAAM;AACd,YAAQ,MAAM,MAAM,UAAU;AAAA,EAEhC,GAAG,CAAC,IAAI,CAAC;AACX;","names":["import_react"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TrackerConfig } from '@litemetrics/tracker';
|
|
3
|
+
|
|
4
|
+
interface LitemetricsProviderProps extends Omit<TrackerConfig, 'autoTrack'> {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
autoPageView?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function LitemetricsProvider({ children, autoPageView, ...config }: LitemetricsProviderProps): react_jsx_runtime.JSX.Element;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Access the Litemetrics tracker instance.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* function Button() {
|
|
16
|
+
* const { track, identify } = useLitemetrics();
|
|
17
|
+
* return <button onClick={() => track('click', { id: 'cta' })}>Click</button>;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function useLitemetrics(): {
|
|
22
|
+
track: (name: string, properties?: Record<string, unknown>) => void;
|
|
23
|
+
identify: (userId: string, traits?: Record<string, unknown>) => void;
|
|
24
|
+
page: (url?: string, title?: string) => void;
|
|
25
|
+
reset: () => void;
|
|
26
|
+
opt_out: () => void;
|
|
27
|
+
opt_in: () => void;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Automatically track page views when the URL changes.
|
|
31
|
+
* Works with React Router, TanStack Router, or any router that updates `location`.
|
|
32
|
+
*
|
|
33
|
+
* @param deps - Dependencies to trigger page view (e.g., pathname from router).
|
|
34
|
+
* If not provided, uses `window.location.href`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // With React Router v6+
|
|
39
|
+
* import { useLocation } from 'react-router-dom';
|
|
40
|
+
* function PageTracker() {
|
|
41
|
+
* const { pathname } = useLocation();
|
|
42
|
+
* usePageView(pathname);
|
|
43
|
+
* return null;
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* // Without router (fallback to window.location)
|
|
47
|
+
* function App() {
|
|
48
|
+
* usePageView();
|
|
49
|
+
* return <div>...</div>;
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function usePageView(pathname?: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Track a custom event when the component mounts.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* function PricingPage() {
|
|
60
|
+
* useTrackEvent('page_section_viewed', { section: 'pricing' });
|
|
61
|
+
* return <div>...</div>;
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function useTrackEvent(name: string, properties?: Record<string, unknown>): void;
|
|
66
|
+
|
|
67
|
+
export { LitemetricsProvider, type LitemetricsProviderProps, useLitemetrics, usePageView, useTrackEvent };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TrackerConfig } from '@litemetrics/tracker';
|
|
3
|
+
|
|
4
|
+
interface LitemetricsProviderProps extends Omit<TrackerConfig, 'autoTrack'> {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
autoPageView?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function LitemetricsProvider({ children, autoPageView, ...config }: LitemetricsProviderProps): react_jsx_runtime.JSX.Element;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Access the Litemetrics tracker instance.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* function Button() {
|
|
16
|
+
* const { track, identify } = useLitemetrics();
|
|
17
|
+
* return <button onClick={() => track('click', { id: 'cta' })}>Click</button>;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function useLitemetrics(): {
|
|
22
|
+
track: (name: string, properties?: Record<string, unknown>) => void;
|
|
23
|
+
identify: (userId: string, traits?: Record<string, unknown>) => void;
|
|
24
|
+
page: (url?: string, title?: string) => void;
|
|
25
|
+
reset: () => void;
|
|
26
|
+
opt_out: () => void;
|
|
27
|
+
opt_in: () => void;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Automatically track page views when the URL changes.
|
|
31
|
+
* Works with React Router, TanStack Router, or any router that updates `location`.
|
|
32
|
+
*
|
|
33
|
+
* @param deps - Dependencies to trigger page view (e.g., pathname from router).
|
|
34
|
+
* If not provided, uses `window.location.href`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // With React Router v6+
|
|
39
|
+
* import { useLocation } from 'react-router-dom';
|
|
40
|
+
* function PageTracker() {
|
|
41
|
+
* const { pathname } = useLocation();
|
|
42
|
+
* usePageView(pathname);
|
|
43
|
+
* return null;
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* // Without router (fallback to window.location)
|
|
47
|
+
* function App() {
|
|
48
|
+
* usePageView();
|
|
49
|
+
* return <div>...</div>;
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function usePageView(pathname?: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Track a custom event when the component mounts.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* function PricingPage() {
|
|
60
|
+
* useTrackEvent('page_section_viewed', { section: 'pricing' });
|
|
61
|
+
* return <div>...</div>;
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function useTrackEvent(name: string, properties?: Record<string, unknown>): void;
|
|
66
|
+
|
|
67
|
+
export { LitemetricsProvider, type LitemetricsProviderProps, useLitemetrics, usePageView, useTrackEvent };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// src/context.tsx
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useMemo } from "react";
|
|
3
|
+
import { createTracker } from "@litemetrics/tracker";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var LitemetricsContext = createContext(null);
|
|
6
|
+
function LitemetricsProvider({
|
|
7
|
+
children,
|
|
8
|
+
autoPageView = true,
|
|
9
|
+
...config
|
|
10
|
+
}) {
|
|
11
|
+
const trackerRef = useRef(null);
|
|
12
|
+
if (!trackerRef.current) {
|
|
13
|
+
trackerRef.current = createTracker({
|
|
14
|
+
...config,
|
|
15
|
+
// Disable built-in auto tracking; we'll handle it via hooks for SPA
|
|
16
|
+
autoTrack: autoPageView && !config.autoSpa,
|
|
17
|
+
autoSpa: false
|
|
18
|
+
// We handle SPA tracking via usePageView hook
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
return () => {
|
|
23
|
+
trackerRef.current?.destroy();
|
|
24
|
+
};
|
|
25
|
+
}, []);
|
|
26
|
+
const value = useMemo(
|
|
27
|
+
() => ({
|
|
28
|
+
tracker: trackerRef.current,
|
|
29
|
+
siteId: config.siteId
|
|
30
|
+
}),
|
|
31
|
+
[config.siteId]
|
|
32
|
+
);
|
|
33
|
+
return /* @__PURE__ */ jsx(LitemetricsContext.Provider, { value, children });
|
|
34
|
+
}
|
|
35
|
+
function useLitemetricsContext() {
|
|
36
|
+
const ctx = useContext(LitemetricsContext);
|
|
37
|
+
if (!ctx) {
|
|
38
|
+
throw new Error("useLitemetrics must be used within <LitemetricsProvider>");
|
|
39
|
+
}
|
|
40
|
+
return ctx;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/hooks.ts
|
|
44
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
45
|
+
function useLitemetrics() {
|
|
46
|
+
const { tracker } = useLitemetricsContext();
|
|
47
|
+
return {
|
|
48
|
+
track: tracker.track.bind(tracker),
|
|
49
|
+
identify: tracker.identify.bind(tracker),
|
|
50
|
+
page: tracker.page.bind(tracker),
|
|
51
|
+
reset: tracker.reset.bind(tracker),
|
|
52
|
+
opt_out: tracker.opt_out.bind(tracker),
|
|
53
|
+
opt_in: tracker.opt_in.bind(tracker)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function usePageView(pathname) {
|
|
57
|
+
const { tracker } = useLitemetricsContext();
|
|
58
|
+
const isFirst = useRef2(true);
|
|
59
|
+
useEffect2(() => {
|
|
60
|
+
if (isFirst.current) {
|
|
61
|
+
isFirst.current = false;
|
|
62
|
+
tracker.page();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
tracker.page();
|
|
66
|
+
}, [pathname, tracker]);
|
|
67
|
+
}
|
|
68
|
+
function useTrackEvent(name, properties) {
|
|
69
|
+
const { tracker } = useLitemetricsContext();
|
|
70
|
+
useEffect2(() => {
|
|
71
|
+
tracker.track(name, properties);
|
|
72
|
+
}, [name]);
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
LitemetricsProvider,
|
|
76
|
+
useLitemetrics,
|
|
77
|
+
usePageView,
|
|
78
|
+
useTrackEvent
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.tsx","../src/hooks.ts"],"sourcesContent":["import { createContext, useContext, useEffect, useRef, useMemo } from 'react';\nimport type { LitemetricsInstance, TrackerConfig } from '@litemetrics/tracker';\nimport { createTracker } from '@litemetrics/tracker';\n\ninterface LitemetricsContextValue {\n tracker: LitemetricsInstance;\n siteId: string;\n}\n\nconst LitemetricsContext = createContext<LitemetricsContextValue | null>(null);\n\nexport interface LitemetricsProviderProps extends Omit<TrackerConfig, 'autoTrack'> {\n children: React.ReactNode;\n autoPageView?: boolean;\n}\n\nexport function LitemetricsProvider({\n children,\n autoPageView = true,\n ...config\n}: LitemetricsProviderProps) {\n const trackerRef = useRef<LitemetricsInstance | null>(null);\n\n if (!trackerRef.current) {\n trackerRef.current = createTracker({\n ...config,\n // Disable built-in auto tracking; we'll handle it via hooks for SPA\n autoTrack: autoPageView && !config.autoSpa,\n autoSpa: false, // We handle SPA tracking via usePageView hook\n });\n }\n\n useEffect(() => {\n return () => {\n trackerRef.current?.destroy();\n };\n }, []);\n\n const value = useMemo<LitemetricsContextValue>(\n () => ({\n tracker: trackerRef.current!,\n siteId: config.siteId,\n }),\n [config.siteId],\n );\n\n return (\n <LitemetricsContext.Provider value={value}>\n {children}\n </LitemetricsContext.Provider>\n );\n}\n\nexport function useLitemetricsContext(): LitemetricsContextValue {\n const ctx = useContext(LitemetricsContext);\n if (!ctx) {\n throw new Error('useLitemetrics must be used within <LitemetricsProvider>');\n }\n return ctx;\n}\n","import { useEffect, useRef } from 'react';\nimport { useLitemetricsContext } from './context';\n\n/**\n * Access the Litemetrics tracker instance.\n *\n * @example\n * ```tsx\n * function Button() {\n * const { track, identify } = useLitemetrics();\n * return <button onClick={() => track('click', { id: 'cta' })}>Click</button>;\n * }\n * ```\n */\nexport function useLitemetrics() {\n const { tracker } = useLitemetricsContext();\n\n return {\n track: tracker.track.bind(tracker),\n identify: tracker.identify.bind(tracker),\n page: tracker.page.bind(tracker),\n reset: tracker.reset.bind(tracker),\n opt_out: tracker.opt_out.bind(tracker),\n opt_in: tracker.opt_in.bind(tracker),\n };\n}\n\n/**\n * Automatically track page views when the URL changes.\n * Works with React Router, TanStack Router, or any router that updates `location`.\n *\n * @param deps - Dependencies to trigger page view (e.g., pathname from router).\n * If not provided, uses `window.location.href`.\n *\n * @example\n * ```tsx\n * // With React Router v6+\n * import { useLocation } from 'react-router-dom';\n * function PageTracker() {\n * const { pathname } = useLocation();\n * usePageView(pathname);\n * return null;\n * }\n *\n * // Without router (fallback to window.location)\n * function App() {\n * usePageView();\n * return <div>...</div>;\n * }\n * ```\n */\nexport function usePageView(pathname?: string) {\n const { tracker } = useLitemetricsContext();\n const isFirst = useRef(true);\n\n useEffect(() => {\n // Skip first render if autoTrack already fired\n if (isFirst.current) {\n isFirst.current = false;\n // Track initial page view\n tracker.page();\n return;\n }\n\n // Track subsequent navigations\n tracker.page();\n }, [pathname, tracker]);\n}\n\n/**\n * Track a custom event when the component mounts.\n *\n * @example\n * ```tsx\n * function PricingPage() {\n * useTrackEvent('page_section_viewed', { section: 'pricing' });\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useTrackEvent(name: string, properties?: Record<string, unknown>) {\n const { tracker } = useLitemetricsContext();\n\n useEffect(() => {\n tracker.track(name, properties);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [name]);\n}\n"],"mappings":";AAAA,SAAS,eAAe,YAAY,WAAW,QAAQ,eAAe;AAEtE,SAAS,qBAAqB;AA6C1B;AAtCJ,IAAM,qBAAqB,cAA8C,IAAI;AAOtE,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,GAA6B;AAC3B,QAAM,aAAa,OAAmC,IAAI;AAE1D,MAAI,CAAC,WAAW,SAAS;AACvB,eAAW,UAAU,cAAc;AAAA,MACjC,GAAG;AAAA;AAAA,MAEH,WAAW,gBAAgB,CAAC,OAAO;AAAA,MACnC,SAAS;AAAA;AAAA,IACX,CAAC;AAAA,EACH;AAEA,YAAU,MAAM;AACd,WAAO,MAAM;AACX,iBAAW,SAAS,QAAQ;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,SAAS,WAAW;AAAA,MACpB,QAAQ,OAAO;AAAA,IACjB;AAAA,IACA,CAAC,OAAO,MAAM;AAAA,EAChB;AAEA,SACE,oBAAC,mBAAmB,UAAnB,EAA4B,OAC1B,UACH;AAEJ;AAEO,SAAS,wBAAiD;AAC/D,QAAM,MAAM,WAAW,kBAAkB;AACzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;;;AC3DA,SAAS,aAAAA,YAAW,UAAAC,eAAc;AAc3B,SAAS,iBAAiB;AAC/B,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAE1C,SAAO;AAAA,IACL,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,IACjC,UAAU,QAAQ,SAAS,KAAK,OAAO;AAAA,IACvC,MAAM,QAAQ,KAAK,KAAK,OAAO;AAAA,IAC/B,OAAO,QAAQ,MAAM,KAAK,OAAO;AAAA,IACjC,SAAS,QAAQ,QAAQ,KAAK,OAAO;AAAA,IACrC,QAAQ,QAAQ,OAAO,KAAK,OAAO;AAAA,EACrC;AACF;AA0BO,SAAS,YAAY,UAAmB;AAC7C,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAC1C,QAAM,UAAUC,QAAO,IAAI;AAE3B,EAAAC,WAAU,MAAM;AAEd,QAAI,QAAQ,SAAS;AACnB,cAAQ,UAAU;AAElB,cAAQ,KAAK;AACb;AAAA,IACF;AAGA,YAAQ,KAAK;AAAA,EACf,GAAG,CAAC,UAAU,OAAO,CAAC;AACxB;AAaO,SAAS,cAAc,MAAc,YAAsC;AAChF,QAAM,EAAE,QAAQ,IAAI,sBAAsB;AAE1C,EAAAA,WAAU,MAAM;AACd,YAAQ,MAAM,MAAM,UAAU;AAAA,EAEhC,GAAG,CAAC,IAAI,CAAC;AACX;","names":["useEffect","useRef","useRef","useEffect"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@litemetrics/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React bindings for Litemetrics analytics (hooks + provider)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Metehan Kurucu",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/metehankurucu/litemetrics",
|
|
10
|
+
"directory": "packages/react"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["analytics", "litemetrics", "react", "hooks", "tracking"],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": ["dist"],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"clean": "rm -rf dist"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@litemetrics/tracker": "0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/react": "^19",
|
|
42
|
+
"react": "^19",
|
|
43
|
+
"tsup": "^8",
|
|
44
|
+
"typescript": "^5.7"
|
|
45
|
+
}
|
|
46
|
+
}
|