react-fathom 0.1.10 → 0.2.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 (80) hide show
  1. package/README.md +941 -25
  2. package/dist/cjs/index.cjs +55 -9
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/native/index.cjs +1079 -0
  5. package/dist/cjs/native/index.cjs.map +1 -0
  6. package/dist/cjs/next/index.cjs +89 -5
  7. package/dist/cjs/next/index.cjs.map +1 -1
  8. package/dist/es/index.js +55 -9
  9. package/dist/es/index.js.map +1 -1
  10. package/dist/es/native/index.js +1071 -0
  11. package/dist/es/native/index.js.map +1 -0
  12. package/dist/es/next/index.js +90 -6
  13. package/dist/es/next/index.js.map +1 -1
  14. package/dist/react-fathom.js +55 -9
  15. package/dist/react-fathom.js.map +1 -1
  16. package/dist/react-fathom.min.js +2 -2
  17. package/dist/react-fathom.min.js.map +1 -1
  18. package/package.json +28 -5
  19. package/src/FathomContext.tsx +30 -1
  20. package/src/FathomProvider.test.tsx +115 -15
  21. package/src/FathomProvider.tsx +10 -2
  22. package/src/components/TrackClick.test.tsx +7 -7
  23. package/src/components/TrackClick.tsx +1 -1
  24. package/src/components/TrackVisible.test.tsx +7 -7
  25. package/src/components/TrackVisible.tsx +1 -1
  26. package/src/hooks/useFathom.test.tsx +14 -3
  27. package/src/hooks/useTrackOnClick.test.tsx +4 -4
  28. package/src/hooks/useTrackOnClick.ts +1 -1
  29. package/src/hooks/useTrackOnVisible.test.tsx +4 -4
  30. package/src/hooks/useTrackOnVisible.ts +1 -1
  31. package/src/index.ts +1 -0
  32. package/src/native/FathomWebView.test.tsx +410 -0
  33. package/src/native/FathomWebView.tsx +297 -0
  34. package/src/native/NativeFathomProvider.test.tsx +372 -0
  35. package/src/native/NativeFathomProvider.tsx +113 -0
  36. package/src/native/createWebViewClient.test.ts +380 -0
  37. package/src/native/createWebViewClient.ts +271 -0
  38. package/src/native/index.ts +29 -0
  39. package/src/native/react-native.d.ts +74 -0
  40. package/src/native/types.ts +145 -0
  41. package/src/native/useAppStateTracking.test.ts +249 -0
  42. package/src/native/useAppStateTracking.ts +66 -0
  43. package/src/native/useNavigationTracking.test.ts +446 -0
  44. package/src/native/useNavigationTracking.ts +177 -0
  45. package/src/next/NextFathomProviderApp.client.tsx +5 -0
  46. package/src/next/NextFathomProviderApp.test.tsx +154 -0
  47. package/src/next/NextFathomProviderApp.tsx +62 -0
  48. package/src/next/index.ts +3 -0
  49. package/src/types.ts +36 -9
  50. package/types/FathomContext.d.ts +1 -1
  51. package/types/FathomContext.d.ts.map +1 -1
  52. package/types/FathomProvider.d.ts.map +1 -1
  53. package/types/components/TrackClick.d.ts +1 -1
  54. package/types/components/TrackVisible.d.ts +1 -1
  55. package/types/hooks/useTrackOnClick.d.ts +1 -1
  56. package/types/hooks/useTrackOnVisible.d.ts +1 -1
  57. package/types/index.d.ts +1 -0
  58. package/types/index.d.ts.map +1 -1
  59. package/types/native/FathomWebView.d.ts +59 -0
  60. package/types/native/FathomWebView.d.ts.map +1 -0
  61. package/types/native/NativeFathomProvider.d.ts +36 -0
  62. package/types/native/NativeFathomProvider.d.ts.map +1 -0
  63. package/types/native/createWebViewClient.d.ts +51 -0
  64. package/types/native/createWebViewClient.d.ts.map +1 -0
  65. package/types/native/index.d.ts +10 -0
  66. package/types/native/index.d.ts.map +1 -0
  67. package/types/native/types.d.ts +125 -0
  68. package/types/native/types.d.ts.map +1 -0
  69. package/types/native/useAppStateTracking.d.ts +25 -0
  70. package/types/native/useAppStateTracking.d.ts.map +1 -0
  71. package/types/native/useNavigationTracking.d.ts +30 -0
  72. package/types/native/useNavigationTracking.d.ts.map +1 -0
  73. package/types/next/NextFathomProviderApp.client.d.ts +3 -0
  74. package/types/next/NextFathomProviderApp.client.d.ts.map +1 -0
  75. package/types/next/NextFathomProviderApp.d.ts +38 -4
  76. package/types/next/NextFathomProviderApp.d.ts.map +1 -1
  77. package/types/next/index.d.ts +1 -0
  78. package/types/next/index.d.ts.map +1 -1
  79. package/types/types.d.ts +34 -9
  80. package/types/types.d.ts.map +1 -1
@@ -0,0 +1,154 @@
1
+ import React from 'react'
2
+
3
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
4
+
5
+ import { render, screen } from '@testing-library/react'
6
+
7
+ import { NextFathomProviderApp } from './NextFathomProviderApp'
8
+
9
+ // Mock FathomProvider and NextFathomTrackViewApp
10
+ vi.mock('../FathomProvider', () => ({
11
+ FathomProvider: ({
12
+ children,
13
+ siteId,
14
+ clientOptions,
15
+ }: {
16
+ children: React.ReactNode
17
+ siteId?: string
18
+ clientOptions?: unknown
19
+ }) => (
20
+ <div
21
+ data-testid="fathom-provider"
22
+ data-site-id={siteId}
23
+ data-client-options={JSON.stringify(clientOptions)}
24
+ >
25
+ {children}
26
+ </div>
27
+ ),
28
+ }))
29
+
30
+ vi.mock('./NextFathomTrackViewApp', () => ({
31
+ NextFathomTrackViewApp: ({
32
+ disableAutoTrack,
33
+ }: {
34
+ disableAutoTrack?: boolean
35
+ }) => (
36
+ <div
37
+ data-testid="track-view-app"
38
+ data-disable-auto-track={disableAutoTrack}
39
+ >
40
+ TrackViewApp
41
+ </div>
42
+ ),
43
+ }))
44
+
45
+ describe('NextFathomProviderApp', () => {
46
+ beforeEach(() => {
47
+ vi.clearAllMocks()
48
+ })
49
+
50
+ it('should render FathomProvider and NextFathomTrackViewApp with children', () => {
51
+ render(
52
+ <NextFathomProviderApp siteId="TEST_SITE_ID">
53
+ <div>Test Content</div>
54
+ </NextFathomProviderApp>,
55
+ )
56
+
57
+ expect(screen.getByTestId('fathom-provider')).toBeInTheDocument()
58
+ expect(screen.getByTestId('fathom-provider')).toHaveAttribute(
59
+ 'data-site-id',
60
+ 'TEST_SITE_ID',
61
+ )
62
+ expect(screen.getByTestId('track-view-app')).toBeInTheDocument()
63
+ expect(screen.getByText('Test Content')).toBeInTheDocument()
64
+ })
65
+
66
+ it('should pass siteId to FathomProvider', () => {
67
+ render(
68
+ <NextFathomProviderApp siteId="MY_SITE_ID">
69
+ <div>Content</div>
70
+ </NextFathomProviderApp>,
71
+ )
72
+
73
+ expect(screen.getByTestId('fathom-provider')).toHaveAttribute(
74
+ 'data-site-id',
75
+ 'MY_SITE_ID',
76
+ )
77
+ })
78
+
79
+ it('should pass disableAutoTrack to NextFathomTrackViewApp', () => {
80
+ render(
81
+ <NextFathomProviderApp siteId="TEST_SITE_ID" disableAutoTrack>
82
+ <div>Content</div>
83
+ </NextFathomProviderApp>,
84
+ )
85
+
86
+ expect(screen.getByTestId('track-view-app')).toHaveAttribute(
87
+ 'data-disable-auto-track',
88
+ 'true',
89
+ )
90
+ })
91
+
92
+ it('should default disableAutoTrack to false', () => {
93
+ render(
94
+ <NextFathomProviderApp siteId="TEST_SITE_ID">
95
+ <div>Content</div>
96
+ </NextFathomProviderApp>,
97
+ )
98
+
99
+ expect(screen.getByTestId('track-view-app')).toHaveAttribute(
100
+ 'data-disable-auto-track',
101
+ 'false',
102
+ )
103
+ })
104
+
105
+ it('should pass clientOptions to FathomProvider', () => {
106
+ const clientOptions = { honorDNT: true, spa: 'auto' }
107
+
108
+ render(
109
+ <NextFathomProviderApp
110
+ siteId="TEST_SITE_ID"
111
+ clientOptions={clientOptions}
112
+ >
113
+ <div>Content</div>
114
+ </NextFathomProviderApp>,
115
+ )
116
+
117
+ const provider = screen.getByTestId('fathom-provider')
118
+ const options = JSON.parse(
119
+ provider.getAttribute('data-client-options') || '{}',
120
+ )
121
+ expect(options).toEqual(clientOptions)
122
+ })
123
+
124
+ it('should pass all FathomProvider props except children and disableAutoTrack', () => {
125
+ render(
126
+ <NextFathomProviderApp
127
+ siteId="TEST_SITE_ID"
128
+ defaultPageviewOptions={{ referrer: 'https://example.com' }}
129
+ defaultEventOptions={{ id: 'test' }}
130
+ >
131
+ <div>Content</div>
132
+ </NextFathomProviderApp>,
133
+ )
134
+
135
+ expect(screen.getByTestId('fathom-provider')).toBeInTheDocument()
136
+ expect(screen.getByText('Content')).toBeInTheDocument()
137
+ })
138
+
139
+ it('should have displayName', () => {
140
+ expect(NextFathomProviderApp.displayName).toBe('NextFathomProviderApp')
141
+ })
142
+
143
+ it('should render multiple children correctly', () => {
144
+ render(
145
+ <NextFathomProviderApp siteId="TEST_SITE_ID">
146
+ <div>Child 1</div>
147
+ <div>Child 2</div>
148
+ </NextFathomProviderApp>,
149
+ )
150
+
151
+ expect(screen.getByText('Child 1')).toBeInTheDocument()
152
+ expect(screen.getByText('Child 2')).toBeInTheDocument()
153
+ })
154
+ })
@@ -0,0 +1,62 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+
5
+ import { FathomProvider } from '../FathomProvider'
6
+ import type { FathomProviderProps } from '../types'
7
+ import { NextFathomTrackViewApp } from './NextFathomTrackViewApp'
8
+
9
+ export interface NextFathomProviderAppProps extends Omit<
10
+ FathomProviderProps,
11
+ 'children'
12
+ > {
13
+ /**
14
+ * Disable automatic pageview tracking on route changes
15
+ * @default false
16
+ */
17
+ disableAutoTrack?: boolean
18
+ /**
19
+ * Child components to render
20
+ */
21
+ children: React.ReactNode
22
+ }
23
+
24
+ /**
25
+ * Client component wrapper that combines FathomProvider and NextFathomTrackViewApp
26
+ * for easy integration in Next.js App Router layouts.
27
+ *
28
+ * This component is marked with 'use client' and can be used directly in Server Components
29
+ * like the root layout.tsx file.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // app/layout.tsx
34
+ * import { NextFathomProviderApp } from 'react-fathom/next'
35
+ *
36
+ * export default function RootLayout({ children }) {
37
+ * return (
38
+ * <html>
39
+ * <body>
40
+ * <NextFathomProviderApp siteId="YOUR_SITE_ID">
41
+ * {children}
42
+ * </NextFathomProviderApp>
43
+ * </body>
44
+ * </html>
45
+ * )
46
+ * }
47
+ * ```
48
+ */
49
+ export const NextFathomProviderApp: React.FC<NextFathomProviderAppProps> = ({
50
+ children,
51
+ disableAutoTrack = false,
52
+ ...fathomProviderProps
53
+ }) => {
54
+ return (
55
+ <FathomProvider {...fathomProviderProps}>
56
+ <NextFathomTrackViewApp disableAutoTrack={disableAutoTrack} />
57
+ {children}
58
+ </FathomProvider>
59
+ )
60
+ }
61
+
62
+ NextFathomProviderApp.displayName = 'NextFathomProviderApp'
package/src/next/index.ts CHANGED
@@ -2,6 +2,9 @@
2
2
  export * from './NextFathomTrackViewPages'
3
3
  export * from './NextFathomTrackViewApp'
4
4
 
5
+ // Convenience provider components for easy setup
6
+ export * from './NextFathomProviderApp'
7
+
5
8
  // Convenience compositions for easy setup
6
9
  export * from './compositions/withPagesRouter'
7
10
  export * from './compositions/withAppRouter'
package/src/types.ts CHANGED
@@ -1,7 +1,10 @@
1
- import type { PropsWithChildren } from 'react'
1
+ import type { MutableRefObject, PropsWithChildren } from 'react'
2
2
 
3
3
  import type { EventOptions, LoadOptions, PageViewOptions } from 'fathom-client'
4
4
 
5
+ // Re-export fathom-client types for convenience
6
+ export type { EventOptions, LoadOptions, PageViewOptions }
7
+
5
8
  export interface FathomClient {
6
9
  blockTrackingForMe: () => void
7
10
  enableTrackingForMe: () => void
@@ -14,14 +17,14 @@ export interface FathomClient {
14
17
  }
15
18
 
16
19
  export interface FathomContextInterface {
17
- blockTrackingForMe?: () => void
18
- enableTrackingForMe?: () => void
19
- isTrackingEnabled?: () => boolean
20
- load?: (siteId: string, options?: LoadOptions) => void
21
- setSite?: (siteId: string) => void
22
- trackPageview?: (options?: PageViewOptions) => void
23
- trackEvent?: (eventName: string, options?: EventOptions) => void
24
- trackGoal?: (code: string, cents: number) => void
20
+ blockTrackingForMe: () => void
21
+ enableTrackingForMe: () => void
22
+ isTrackingEnabled: () => boolean
23
+ load: (siteId: string, options?: LoadOptions) => void
24
+ setSite: (siteId: string) => void
25
+ trackPageview: (options?: PageViewOptions) => void
26
+ trackEvent: (eventName: string, options?: EventOptions) => void
27
+ trackGoal: (code: string, cents: number) => void
25
28
  client?: FathomClient
26
29
  defaultPageviewOptions?: PageViewOptions
27
30
  defaultEventOptions?: EventOptions
@@ -29,6 +32,30 @@ export interface FathomContextInterface {
29
32
 
30
33
  export interface FathomProviderProps extends PropsWithChildren {
31
34
  client?: FathomClient
35
+ /**
36
+ * A ref that will be populated with the resolved Fathom client instance.
37
+ * This allows the parent component that composes the provider to access
38
+ * the client directly, since it cannot use useFathom() (context only flows
39
+ * downward to children).
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * function App() {
44
+ * const clientRef = useRef<FathomClient>(null);
45
+ *
46
+ * const handleDeepLink = (url: string) => {
47
+ * clientRef.current?.trackEvent('deep_link', { _url: url });
48
+ * };
49
+ *
50
+ * return (
51
+ * <FathomProvider siteId="..." clientRef={clientRef}>
52
+ * <YourApp />
53
+ * </FathomProvider>
54
+ * );
55
+ * }
56
+ * ```
57
+ */
58
+ clientRef?: MutableRefObject<FathomClient | null>
32
59
  clientOptions?: LoadOptions
33
60
  siteId?: string
34
61
  defaultPageviewOptions?: PageViewOptions
@@ -1,3 +1,3 @@
1
1
  import type { FathomContextInterface } from './types';
2
- export declare const FathomContext: import("react").Context<Partial<FathomContextInterface>>;
2
+ export declare const FathomContext: import("react").Context<FathomContextInterface>;
3
3
  //# sourceMappingURL=FathomContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FathomContext.d.ts","sourceRoot":"","sources":["../src/FathomContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAErD,eAAO,MAAM,aAAa,0DAAqD,CAAA"}
1
+ {"version":3,"file":"FathomContext.d.ts","sourceRoot":"","sources":["../src/FathomContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AA8BrD,eAAO,MAAM,aAAa,iDACkC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"FathomProvider.d.ts","sourceRoot":"","sources":["../src/FathomProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsD,MAAM,OAAO,CAAA;AAM1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA4GjD,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
1
+ {"version":3,"file":"FathomProvider.d.ts","sourceRoot":"","sources":["../src/FathomProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsD,MAAM,OAAO,CAAA;AAM1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAoHjD,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
@@ -30,7 +30,7 @@ export interface TrackClickProps extends EventOptions {
30
30
  *
31
31
  * @example
32
32
  * ```tsx
33
- * <TrackClick eventName="cta-clicked" id="hero-cta">
33
+ * <TrackClick eventName="cta-clicked" _value={100}>
34
34
  * <button>Get Started</button>
35
35
  * </TrackClick>
36
36
  * ```
@@ -30,7 +30,7 @@ export interface TrackVisibleProps extends EventOptions {
30
30
  *
31
31
  * @example
32
32
  * ```tsx
33
- * <TrackVisible eventName="section-viewed" section="hero">
33
+ * <TrackVisible eventName="section-viewed" _value={1}>
34
34
  * <HeroSection />
35
35
  * </TrackVisible>
36
36
  * ```
@@ -24,7 +24,7 @@ export interface UseTrackOnClickOptions extends EventOptions {
24
24
  * function Button() {
25
25
  * const handleClick = useTrackOnClick({
26
26
  * eventName: 'button-click',
27
- * id: 'signup-button',
27
+ * _value: 100, // Optional: value in cents
28
28
  * callback: (e) => {
29
29
  * console.log('Button clicked!')
30
30
  * // Your custom logic here
@@ -28,7 +28,7 @@ export interface UseTrackOnVisibleOptions extends EventOptions {
28
28
  * function Section() {
29
29
  * const ref = useTrackOnVisible({
30
30
  * eventName: 'section-viewed',
31
- * section: 'hero',
31
+ * _value: 1, // Optional: value in cents
32
32
  * callback: (entry) => {
33
33
  * console.log('Section is visible!', entry.isIntersecting)
34
34
  * // Your custom logic here
package/types/index.d.ts CHANGED
@@ -2,4 +2,5 @@ export * from './FathomContext';
2
2
  export * from './FathomProvider';
3
3
  export * from './hooks';
4
4
  export * from './components';
5
+ export * from './types';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA"}
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import type { EventOptions, PageViewOptions, LoadOptions } from '../types';
3
+ export interface FathomWebViewRef {
4
+ trackPageview: (opts?: PageViewOptions) => void;
5
+ trackEvent: (eventName: string, opts?: EventOptions) => void;
6
+ trackGoal: (code: string, cents: number) => void;
7
+ blockTrackingForMe: () => void;
8
+ enableTrackingForMe: () => void;
9
+ isReady: () => boolean;
10
+ }
11
+ export interface FathomWebViewProps {
12
+ /**
13
+ * Your Fathom Analytics site ID
14
+ */
15
+ siteId: string;
16
+ /**
17
+ * Options passed to fathom.load()
18
+ */
19
+ loadOptions?: LoadOptions;
20
+ /**
21
+ * Custom domain for Fathom script (if using custom domains feature)
22
+ * @default 'cdn.usefathom.com'
23
+ */
24
+ scriptDomain?: string;
25
+ /**
26
+ * Called when the Fathom script has loaded and is ready
27
+ */
28
+ onReady?: () => void;
29
+ /**
30
+ * Called when an error occurs loading the script
31
+ */
32
+ onError?: (error: string) => void;
33
+ /**
34
+ * Enable debug logging
35
+ */
36
+ debug?: boolean;
37
+ }
38
+ /**
39
+ * Hidden WebView component that loads and manages the Fathom Analytics script.
40
+ *
41
+ * This component renders an invisible WebView that loads the official Fathom
42
+ * tracking script, allowing React Native apps to use Fathom's full functionality.
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * const fathomRef = useRef<FathomWebViewRef>(null)
47
+ *
48
+ * <FathomWebView
49
+ * ref={fathomRef}
50
+ * siteId="ABCDEFGH"
51
+ * onReady={() => console.log('Fathom ready!')}
52
+ * />
53
+ *
54
+ * // Later, track events:
55
+ * fathomRef.current?.trackPageview({ url: '/home' })
56
+ * ```
57
+ */
58
+ export declare const FathomWebView: React.ForwardRefExoticComponent<FathomWebViewProps & React.RefAttributes<FathomWebViewRef>>;
59
+ //# sourceMappingURL=FathomWebView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FathomWebView.d.ts","sourceRoot":"","sources":["../../src/native/FathomWebView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAA;AAId,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,eAAe,KAAK,IAAI,CAAA;IAC/C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;IAC5D,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChD,kBAAkB,EAAE,MAAM,IAAI,CAAA;IAC9B,mBAAmB,EAAE,MAAM,IAAI,CAAA;IAC/B,OAAO,EAAE,MAAM,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEjC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,6FAgNzB,CAAA"}
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import type { NativeFathomProviderProps } from './types';
3
+ /**
4
+ * A convenience provider for React Native apps that uses a hidden WebView
5
+ * to load the official Fathom Analytics script.
6
+ *
7
+ * This approach ensures full compatibility with Fathom's tracking by using
8
+ * their official JavaScript client, while providing a native React API.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { NativeFathomProvider } from 'react-fathom/native'
13
+ *
14
+ * function App() {
15
+ * return (
16
+ * <NativeFathomProvider
17
+ * siteId="YOUR_SITE_ID"
18
+ * debug={__DEV__}
19
+ * trackAppState
20
+ * >
21
+ * <YourApp />
22
+ * </NativeFathomProvider>
23
+ * )
24
+ * }
25
+ * ```
26
+ *
27
+ * @remarks
28
+ * This component renders a hidden WebView that loads Fathom's tracking script.
29
+ * Events are queued until the WebView is ready, then automatically flushed.
30
+ *
31
+ * The WebView approach is used because Fathom Analytics does not currently
32
+ * provide a public API for server-side or mobile event tracking. This ensures
33
+ * your analytics are recorded correctly using Fathom's official client.
34
+ */
35
+ export declare const NativeFathomProvider: React.FC<NativeFathomProviderProps>;
36
+ //# sourceMappingURL=NativeFathomProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeFathomProvider.d.ts","sourceRoot":"","sources":["../../src/native/NativeFathomProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAA;AAMtE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAcxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA4DpE,CAAA"}
@@ -0,0 +1,51 @@
1
+ import type { FathomClient } from '../types';
2
+ import type { FathomWebViewRef } from './FathomWebView';
3
+ export interface WebViewClientOptions {
4
+ /**
5
+ * Enable debug logging (default: false)
6
+ */
7
+ debug?: boolean;
8
+ /**
9
+ * Enable offline event queuing (default: true)
10
+ * When enabled, events are queued if the WebView isn't ready yet
11
+ */
12
+ enableQueue?: boolean;
13
+ /**
14
+ * Maximum number of events to queue (default: 100)
15
+ */
16
+ maxQueueSize?: number;
17
+ }
18
+ /**
19
+ * Creates a Fathom client that communicates with a FathomWebView component.
20
+ *
21
+ * This client queues commands until the WebView is ready, then flushes them.
22
+ * It implements the standard FathomClient interface for compatibility with
23
+ * the FathomProvider component.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { createWebViewClient, FathomWebView } from 'react-fathom/native'
28
+ *
29
+ * function App() {
30
+ * const webViewRef = useRef<FathomWebViewRef>(null)
31
+ * const client = useMemo(
32
+ * () => createWebViewClient(() => webViewRef.current, { debug: __DEV__ }),
33
+ * []
34
+ * )
35
+ *
36
+ * return (
37
+ * <FathomProvider client={client} siteId="YOUR_SITE_ID">
38
+ * <FathomWebView ref={webViewRef} siteId="YOUR_SITE_ID" />
39
+ * <YourApp />
40
+ * </FathomProvider>
41
+ * )
42
+ * }
43
+ * ```
44
+ */
45
+ export interface WebViewFathomClient extends FathomClient {
46
+ processQueue: () => number;
47
+ getQueueLength: () => number;
48
+ setWebViewReady: () => void;
49
+ }
50
+ export declare function createWebViewClient(getWebViewRef: () => FathomWebViewRef | null | undefined, options?: WebViewClientOptions): WebViewFathomClient;
51
+ //# sourceMappingURL=createWebViewClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWebViewClient.d.ts","sourceRoot":"","sources":["../../src/native/createWebViewClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA8C,MAAM,UAAU,CAAA;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,YAAY,EAAE,MAAM,MAAM,CAAA;IAC1B,cAAc,EAAE,MAAM,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAA;CAC5B;AAED,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,gBAAgB,GAAG,IAAI,GAAG,SAAS,EACxD,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CA+MrB"}
@@ -0,0 +1,10 @@
1
+ export { FathomWebView, type FathomWebViewRef, type FathomWebViewProps } from './FathomWebView';
2
+ export { createWebViewClient, type WebViewFathomClient, type WebViewClientOptions } from './createWebViewClient';
3
+ export { NativeFathomProvider } from './NativeFathomProvider';
4
+ export { FathomProvider } from '../FathomProvider';
5
+ export { useFathom } from '../hooks/useFathom';
6
+ export { useAppStateTracking } from './useAppStateTracking';
7
+ export { useNavigationTracking } from './useNavigationTracking';
8
+ export type { NativeFathomProviderProps, UseNavigationTrackingOptions, UseAppStateTrackingOptions, FathomClient, EventOptions, LoadOptions, PageViewOptions, } from './types';
9
+ export type { FathomContextInterface, FathomProviderProps, } from '../types';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAC/F,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAGhH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGlD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAG/D,YAAY,EACV,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAE1B,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,eAAe,GAChB,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,UAAU,CAAA"}
@@ -0,0 +1,125 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import type { FathomClient, EventOptions, LoadOptions, PageViewOptions } from '../types';
3
+ import type { WebViewFathomClient } from './createWebViewClient';
4
+ /**
5
+ * Options for the NativeFathomProvider component
6
+ */
7
+ export interface NativeFathomProviderProps {
8
+ /**
9
+ * Your Fathom Analytics site ID
10
+ */
11
+ siteId: string;
12
+ /**
13
+ * Options passed to fathom.load() in the WebView
14
+ */
15
+ loadOptions?: LoadOptions;
16
+ /**
17
+ * Custom domain for Fathom script (if using Fathom's custom domains feature)
18
+ * @default 'cdn.usefathom.com'
19
+ */
20
+ scriptDomain?: string;
21
+ /**
22
+ * Default options merged into all trackPageview calls
23
+ */
24
+ defaultPageviewOptions?: PageViewOptions;
25
+ /**
26
+ * Default options merged into all trackEvent calls
27
+ */
28
+ defaultEventOptions?: EventOptions;
29
+ /**
30
+ * Enable automatic app state tracking (foreground/background)
31
+ * Tracks 'app-foreground' and 'app-background' events
32
+ * @default false
33
+ */
34
+ trackAppState?: boolean;
35
+ /**
36
+ * Enable debug logging
37
+ * @default false
38
+ */
39
+ debug?: boolean;
40
+ /**
41
+ * Called when the Fathom script has loaded and is ready
42
+ */
43
+ onReady?: () => void;
44
+ /**
45
+ * Called when an error occurs loading the script
46
+ */
47
+ onError?: (error: string) => void;
48
+ /**
49
+ * A ref that will be populated with the WebView-based Fathom client instance.
50
+ * This allows the parent component that composes the provider to access
51
+ * the client directly, since it cannot use useFathom() (context only flows
52
+ * downward to children).
53
+ *
54
+ * The client is a WebViewFathomClient which extends FathomClient with
55
+ * additional methods for queue management.
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * import { NativeFathomProvider, WebViewFathomClient } from 'react-fathom/native'
60
+ *
61
+ * function App() {
62
+ * const clientRef = useRef<WebViewFathomClient>(null);
63
+ *
64
+ * const handleDeepLink = (url: string) => {
65
+ * clientRef.current?.trackEvent('deep_link', { _url: url });
66
+ * };
67
+ *
68
+ * return (
69
+ * <NativeFathomProvider siteId="..." clientRef={clientRef}>
70
+ * <YourApp />
71
+ * </NativeFathomProvider>
72
+ * );
73
+ * }
74
+ * ```
75
+ */
76
+ clientRef?: MutableRefObject<WebViewFathomClient | null>;
77
+ /**
78
+ * Children to render
79
+ */
80
+ children: React.ReactNode;
81
+ }
82
+ /**
83
+ * Options for the useNavigationTracking hook
84
+ */
85
+ export interface UseNavigationTrackingOptions {
86
+ /**
87
+ * React Navigation navigation container ref
88
+ */
89
+ navigationRef: React.RefObject<any>;
90
+ /**
91
+ * Transform the route name before tracking (e.g., add prefixes)
92
+ */
93
+ transformRouteName?: (routeName: string) => string;
94
+ /**
95
+ * Filter which routes should be tracked (return false to skip)
96
+ */
97
+ shouldTrackRoute?: (routeName: string, params?: Record<string, any>) => boolean;
98
+ /**
99
+ * Include route params in the tracked URL
100
+ */
101
+ includeParams?: boolean;
102
+ }
103
+ /**
104
+ * Options for the useAppStateTracking hook
105
+ */
106
+ export interface UseAppStateTrackingOptions {
107
+ /**
108
+ * Event name for when the app comes to foreground (default: 'app-foreground')
109
+ */
110
+ foregroundEventName?: string;
111
+ /**
112
+ * Event name for when the app goes to background (default: 'app-background')
113
+ */
114
+ backgroundEventName?: string;
115
+ /**
116
+ * Additional event options to include with app state events
117
+ */
118
+ eventOptions?: EventOptions;
119
+ /**
120
+ * Callback when app state changes
121
+ */
122
+ onStateChange?: (state: 'active' | 'background' | 'inactive') => void;
123
+ }
124
+ export type { FathomClient, EventOptions, LoadOptions, PageViewOptions };
125
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/native/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AACxF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAEhE;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,sBAAsB,CAAC,EAAE,eAAe,CAAA;IAExC;;OAEG;IACH,mBAAmB,CAAC,EAAE,YAAY,CAAA;IAElC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAExD;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAEnC;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IAElD;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAA;IAE/E;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAE5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAE5B;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,KAAK,IAAI,CAAA;CACtE;AAGD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA"}