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.
- package/README.md +941 -25
- package/dist/cjs/index.cjs +55 -9
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/native/index.cjs +1079 -0
- package/dist/cjs/native/index.cjs.map +1 -0
- package/dist/cjs/next/index.cjs +89 -5
- package/dist/cjs/next/index.cjs.map +1 -1
- package/dist/es/index.js +55 -9
- package/dist/es/index.js.map +1 -1
- package/dist/es/native/index.js +1071 -0
- package/dist/es/native/index.js.map +1 -0
- package/dist/es/next/index.js +90 -6
- package/dist/es/next/index.js.map +1 -1
- package/dist/react-fathom.js +55 -9
- package/dist/react-fathom.js.map +1 -1
- package/dist/react-fathom.min.js +2 -2
- package/dist/react-fathom.min.js.map +1 -1
- package/package.json +28 -5
- package/src/FathomContext.tsx +30 -1
- package/src/FathomProvider.test.tsx +115 -15
- package/src/FathomProvider.tsx +10 -2
- package/src/components/TrackClick.test.tsx +7 -7
- package/src/components/TrackClick.tsx +1 -1
- package/src/components/TrackVisible.test.tsx +7 -7
- package/src/components/TrackVisible.tsx +1 -1
- package/src/hooks/useFathom.test.tsx +14 -3
- package/src/hooks/useTrackOnClick.test.tsx +4 -4
- package/src/hooks/useTrackOnClick.ts +1 -1
- package/src/hooks/useTrackOnVisible.test.tsx +4 -4
- package/src/hooks/useTrackOnVisible.ts +1 -1
- package/src/index.ts +1 -0
- package/src/native/FathomWebView.test.tsx +410 -0
- package/src/native/FathomWebView.tsx +297 -0
- package/src/native/NativeFathomProvider.test.tsx +372 -0
- package/src/native/NativeFathomProvider.tsx +113 -0
- package/src/native/createWebViewClient.test.ts +380 -0
- package/src/native/createWebViewClient.ts +271 -0
- package/src/native/index.ts +29 -0
- package/src/native/react-native.d.ts +74 -0
- package/src/native/types.ts +145 -0
- package/src/native/useAppStateTracking.test.ts +249 -0
- package/src/native/useAppStateTracking.ts +66 -0
- package/src/native/useNavigationTracking.test.ts +446 -0
- package/src/native/useNavigationTracking.ts +177 -0
- package/src/next/NextFathomProviderApp.client.tsx +5 -0
- package/src/next/NextFathomProviderApp.test.tsx +154 -0
- package/src/next/NextFathomProviderApp.tsx +62 -0
- package/src/next/index.ts +3 -0
- package/src/types.ts +36 -9
- package/types/FathomContext.d.ts +1 -1
- package/types/FathomContext.d.ts.map +1 -1
- package/types/FathomProvider.d.ts.map +1 -1
- package/types/components/TrackClick.d.ts +1 -1
- package/types/components/TrackVisible.d.ts +1 -1
- package/types/hooks/useTrackOnClick.d.ts +1 -1
- package/types/hooks/useTrackOnVisible.d.ts +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/native/FathomWebView.d.ts +59 -0
- package/types/native/FathomWebView.d.ts.map +1 -0
- package/types/native/NativeFathomProvider.d.ts +36 -0
- package/types/native/NativeFathomProvider.d.ts.map +1 -0
- package/types/native/createWebViewClient.d.ts +51 -0
- package/types/native/createWebViewClient.d.ts.map +1 -0
- package/types/native/index.d.ts +10 -0
- package/types/native/index.d.ts.map +1 -0
- package/types/native/types.d.ts +125 -0
- package/types/native/types.d.ts.map +1 -0
- package/types/native/useAppStateTracking.d.ts +25 -0
- package/types/native/useAppStateTracking.d.ts.map +1 -0
- package/types/native/useNavigationTracking.d.ts +30 -0
- package/types/native/useNavigationTracking.d.ts.map +1 -0
- package/types/next/NextFathomProviderApp.client.d.ts +3 -0
- package/types/next/NextFathomProviderApp.client.d.ts.map +1 -0
- package/types/next/NextFathomProviderApp.d.ts +38 -4
- package/types/next/NextFathomProviderApp.d.ts.map +1 -1
- package/types/next/index.d.ts +1 -0
- package/types/next/index.d.ts.map +1 -1
- package/types/types.d.ts +34 -9
- 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
|
|
18
|
-
enableTrackingForMe
|
|
19
|
-
isTrackingEnabled
|
|
20
|
-
load
|
|
21
|
-
setSite
|
|
22
|
-
trackPageview
|
|
23
|
-
trackEvent
|
|
24
|
-
trackGoal
|
|
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
|
package/types/FathomContext.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FathomContextInterface } from './types';
|
|
2
|
-
export declare const FathomContext: import("react").Context<
|
|
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;
|
|
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,
|
|
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"}
|
|
@@ -24,7 +24,7 @@ export interface UseTrackOnClickOptions extends EventOptions {
|
|
|
24
24
|
* function Button() {
|
|
25
25
|
* const handleClick = useTrackOnClick({
|
|
26
26
|
* eventName: 'button-click',
|
|
27
|
-
*
|
|
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
|
-
*
|
|
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
package/types/index.d.ts.map
CHANGED
|
@@ -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"}
|