Skip to content

Commit 1fc1f8d

Browse files
Merge pull request #183 from fingerprintjs/feature/INTER-1708-agent-v4
[INTER-1708] Add support for Agent V4
2 parents 3bbc4da + c8eca76 commit 1fc1f8d

69 files changed

Lines changed: 4123 additions & 1548 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/coverage-diff.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ jobs:
1010
checks: write
1111
pull-requests: write
1212
uses: fingerprintjs/dx-team-toolkit/.github/workflows/coverage-diff.yml@v1
13+
with:
14+
testScript: pnpm test:coverage:diff

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
uses: fingerprintjs/dx-team-toolkit/.github/workflows/release-typescript-project.yml@v1
1212
with:
1313
appId: ${{ vars.APP_ID }}
14+
useTrustedPublishing: true
1415
secrets:
1516
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
1617
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

.releaserc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
}
2222
],
2323
"@semantic-release/changelog",
24-
"@semantic-release/npm",
24+
[
25+
"@semantic-release/npm",
26+
{
27+
"npmPublish": false
28+
}
29+
],
2530
[
2631
"@semantic-release/exec",
2732
{

README.md

Lines changed: 38 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@
88
</a>
99
</p>
1010
<p align="center">
11-
<a href="https://github.com/fingerprintjs/fingerprintjs-pro-react/actions/workflows/release.yml"><img src="https://github.com/fingerprintjs/fingerprintjs-pro-react/actions/workflows/release.yml/badge.svg" alt="CI badge" /></a>
12-
<a href="https://fingerprintjs.github.io/fingerprintjs-pro-react/coverage/"><img src="https://fingerprintjs.github.io/fingerprintjs-pro-react/coverage/badges.svg" alt="coverage"></a>
13-
<a href="https://www.npmjs.com/package/@fingerprintjs/fingerprintjs-pro-react"><img src="https://img.shields.io/npm/v/@fingerprintjs/fingerprintjs-pro-react.svg" alt="Current NPM version"></a>
14-
<a href="https://www.npmjs.com/package/@fingerprintjs/fingerprintjs-pro-react"><img src="https://img.shields.io/npm/dm/@fingerprintjs/fingerprintjs-pro-react.svg" alt="Monthly downloads from NPM"></a>
11+
<a href="https://github.com/fingerprintjs/react/actions/workflows/release.yml"><img src="https://github.com/fingerprintjs/react/actions/workflows/release.yml/badge.svg" alt="CI badge" /></a>
12+
<a href="https://fingerprintjs.github.io/react/coverage/"><img src="https://fingerprintjs.github.io/react/coverage/badges.svg" alt="coverage"></a>
13+
<a href="https://www.npmjs.com/package/@fingerprint/react"><img src="https://img.shields.io/npm/v/@fingerprint/react.svg" alt="Current NPM version"></a>
14+
<a href="https://www.npmjs.com/package/@fingerprint/react"><img src="https://img.shields.io/npm/dm/@fingerprint/react.svg" alt="Monthly downloads from NPM"></a>
1515
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/:license-mit-blue.svg" alt="MIT license"></a>
1616
<a href="https://discord.gg/39EpE2neBg"><img src="https://img.shields.io/discord/852099967190433792?style=logo&label=Discord&logo=Discord&logoColor=white" alt="Discord server"></a>
17-
<a href="https://fingerprintjs.github.io/fingerprintjs-pro-react/"><img src="https://img.shields.io/badge/-Documentation-green" alt="Discord server"></a>
17+
<a href="https://fingerprintjs.github.io/react/"><img src="https://img.shields.io/badge/-Documentation-green" alt="Discord server"></a>
1818
</p>
1919

20-
# Fingerprint Pro React
20+
# Fingerprint React
2121

22-
Fingerprint is a device intelligence platform offering industry-leading accuracy. Fingerprint Pro React SDK is an easy way to integrate **[Fingerprint Pro](https://fingerprint.com/)** into your React application. It's also compatible with Next.js and Preact. See application demos in the [examples](https://github.com/fingerprintjs/fingerprintjs-pro-react/tree/main/examples) folder.
22+
Fingerprint is a device intelligence platform offering industry-leading accuracy. Fingerprint React SDK is an easy way to integrate **[Fingerprint](https://fingerprint.com/)** into your React application. It's also compatible with Next.js and Preact. See application demos in the [examples](https://github.com/fingerprintjs/react/tree/main/examples) folder.
2323

2424
## Table of contents
2525

2626

27-
- [Fingerprint Pro React](#fingerprint-pro-react)
27+
- [Fingerprint React](#fingerprint-react)
2828
- [Table of contents](#table-of-contents)
2929
- [Requirements](#requirements)
3030
- [Installation](#installation)
3131
- [Getting started](#getting-started)
32-
- [1. Wrap your application (or component) in `<FpjsProvider>`.](#1-wrap-your-application-or-component-in-fpjsprovider)
32+
- [1. Wrap your application (or component) in `<FingerprintProvider>`.](#1-wrap-your-application-or-component-in-FingerprintProvider)
3333
- [2. Use the `useVisitorData()` hook in your components to identify visitors](#2-use-the-usevisitordata-hook-in-your-components-to-identify-visitors)
3434
- [Linking and tagging information](#linking-and-tagging-information)
3535
- [Caching strategy](#caching-strategy)
@@ -46,69 +46,59 @@ Fingerprint is a device intelligence platform offering industry-leading accuracy
4646
- For Typescript users: Typescript 4.8 or higher
4747

4848
> [!NOTE]
49-
> This package assumes you have a Fingerprint Pro subscription or trial, it is not compatible with the [source-available FingerprintJS](https://github.com/fingerprintjs/fingerprintjs). See our documentation to learn more about the [differences between Fingerprint Pro and FingerprintJS](https://dev.fingerprint.com/docs/identification-vs-fingerprintjs).
49+
> This package assumes you have a Fingerprint subscription or trial, it is not compatible with the [source-available FingerprintJS](https://github.com/fingerprintjs/fingerprintjs). See our documentation to learn more about the [differences between Fingerprint and FingerprintJS](https://docs.fingerprint.com/docs/identification-vs-fingerprintjs).
5050
5151
## Installation
5252

5353
Using [npm](https://npmjs.org):
5454

5555
```sh
56-
npm install @fingerprintjs/fingerprintjs-pro-react
56+
npm install @fingerprint/react
5757
```
5858

5959
Using [yarn](https://yarnpkg.com):
6060

6161
```sh
62-
yarn add @fingerprintjs/fingerprintjs-pro-react
62+
yarn add @fingerprint/react
6363
```
6464

6565
Using [pnpm](https://pnpm.js.org):
6666

6767
```sh
68-
pnpm add @fingerprintjs/fingerprintjs-pro-react
68+
pnpm add @fingerprint/react
6969
```
7070

7171
## Getting started
7272

73-
In order to identify visitors, you'll need a Fingerprint Pro account (you can [sign up for free](https://dashboard.fingerprint.com/signup/)).
74-
To get your API key and get started, see the [Fingerprint Pro Quick Start Guide](https://dev.fingerprint.com/docs/quick-start-guide).
73+
In order to identify visitors, you'll need a Fingerprint account (you can [sign up for free](https://dashboard.fingerprint.com/signup/)).
74+
To get your API key and get started, see the [Fingerprint Quick Start Guide](https://docs.fingerprint.com/docs/quick-start-guide).
7575

76-
### 1. Wrap your application (or component) in `<FpjsProvider>`.
76+
### 1. Wrap your application (or component) in `<FingerprintProvider>`.
7777

7878
- Set `apiKey` to your Fingerprint [Public API Key](https://dashboard.fingerprint.com/api-keys).
79-
- Set `region` if you have chosen a non-global [region](https://dev.fingerprint.com/docs/regions) during registration.
80-
- Set `endpoint` and `scriptUrlPattern` if you are using [one of our proxy integrations to increase accuracy](https://dev.fingerprint.com/docs/protecting-the-javascript-agent-from-adblockers) and effectiveness of visitor identification.
81-
- You can use all the [load options](https://dev.fingerprint.com/reference/load-function#load-options) available in the JavaScript agent `load` function.
79+
- Set `region` if you have chosen a non-global [region](https://docs.fingerprint.com/docs/regions) during registration.
80+
- Set `endpoint` if you are using [one of our proxy integrations to increase accuracy](https://docs.fingerprint.com/docs/protecting-the-javascript-agent-from-adblockers) and effectiveness of visitor identification.
81+
- You can use all the [start options](https://docs.fingerprint.com/reference/js-agent-v4-start-function#start-options) available in the JavaScript agent `load` function.
8282

8383
```jsx
8484
// src/index.js
8585
import React from 'react'
8686
import ReactDOM from 'react-dom/client'
8787
import {
88-
FpjsProvider,
88+
FingerprintProvider,
8989
FingerprintJSPro,
90-
} from '@fingerprintjs/fingerprintjs-pro-react'
90+
} from '@fingerprint/react'
9191
import App from './App'
9292

9393
const root = ReactDOM.createRoot(document.getElementById('app'))
9494

95+
// <FingerprintProvider /> supports the same options as `start()` function.
9596
root.render(
96-
<FpjsProvider
97-
loadOptions={{
98-
apiKey: 'your-public-api-key',
99-
// region: 'eu',
100-
endpoint: [
101-
// 'metrics.yourwebsite.com',
102-
FingerprintJSPro.defaultEndpoint,
103-
],
104-
scriptUrlPattern: [
105-
// 'https://metrics.yourwebsite.com/web/v<version>/<apiKey>/loader_v<loaderVersion>.js',
106-
FingerprintJSPro.defaultScriptUrlPattern,
107-
],
108-
}}
97+
<FingerprintProvider
98+
apiKey='your-public-api-key'
10999
>
110100
<App />
111-
</FpjsProvider>
101+
</FingerprintProvider>
112102
)
113103
```
114104

@@ -117,10 +107,10 @@ root.render(
117107
```jsx
118108
// src/App.js
119109
import React from 'react'
120-
import { useVisitorData } from '@fingerprintjs/fingerprintjs-pro-react'
110+
import { useVisitorData } from '@fingerprint/react'
121111

122112
function App() {
123-
const { isLoading, error, data } = useVisitorData()
113+
const { isLoading, error, isFetched, data } = useVisitorData()
124114

125115
if (isLoading) {
126116
return <div>Loading...</div>
@@ -129,36 +119,29 @@ function App() {
129119
return <div>An error occured: {error.message}</div>
130120
}
131121

132-
if (data) {
133-
// Perform some logic based on the visitor data
134-
return (
135-
<div>
136-
Welcome {data.visitorFound ? 'back' : ''}, {data.visitorId}!
137-
</div>
138-
)
139-
} else {
140-
return null
122+
if (isFetched) {
123+
return <div>Welcome {data.visitor_id}!</div>
141124
}
125+
126+
return null
142127
}
143128

144129
export default App
145130
```
146131

147132
The `useVisitorData` hook also returns a `getData` method you can use to make an API call on command.
148133

149-
- You can pass `{ ignoreCache: true }` to `useVisitorData` to force a fresh identification request.
150134
- You can pass `{ immediate: false }` to `useVisitorData` to disable automatic visitor identification on render.
151135

152-
Both `useVisitorData` and `getData` accept all the [get options](https://dev.fingerprint.com/reference/get-function#get-options) available in the JavaScript agent `get` function.
136+
Both `useVisitorData` and `getData` accept all the [get options](https://docs.fingerprint.com/reference/get-function#get-options) available in the JavaScript agent `get` function.
153137

154138
```jsx
155139
// src/App.js
156140
import React, { useState } from 'react'
157-
import { useVisitorData } from '@fingerprintjs/fingerprintjs-pro-react'
141+
import { useVisitorData } from '@fingerprint/react'
158142

159143
function App() {
160144
const { isLoading, error, getData } = useVisitorData(
161-
{ ignoreCache: true },
162145
{ immediate: false }
163146
)
164147
const [email, setEmail] = useState('')
@@ -206,7 +189,7 @@ export default App
206189

207190
## Linking and tagging information
208191

209-
The `visitorId` provided by Fingerprint Identification is especially useful when combined with information you already know about your users, for example, account IDs, order IDs, etc. To learn more about various applications of the `linkedId` and `tag`, see [Linking and tagging information](https://dev.fingerprint.com/docs/tagging-information).
192+
The `visitorId` provided by Fingerprint Identification is especially useful when combined with information you already know about your users, for example, account IDs, order IDs, etc. To learn more about various applications of the `linkedId` and `tag`, see [Linking and tagging information](https://docs.fingerprint.com/docs/tagging-information).
210193

211194
Associate the visitor ID with your data using the `linkedId` or `tag` parameter of the options object passed into the `useVisitorData()` hook or the `getData` function:
212195

@@ -224,32 +207,18 @@ function App() {
224207
// ...
225208
```
226209

227-
## Caching strategy
228-
229-
Fingerprint Pro usage is billed per API call. To avoid unnecessary API calls, it is a good practice to cache identification results. By default, the SDK uses `sessionStorage` to cache results.
230-
231-
- Specify the `cacheLocation` prop on `<FpjsProvider>` to instead store results in `memory` or `localStorage`. Use `none` to disable caching completely.
232-
- Specify the `cacheTimeInSeconds` prop on `<FpjsProvider>` to set the cache time in seconds. It cannot exceed 86400 seconds (24 hours).
233-
- Specify the `cache` prop on `<FpjsProvider>` to use your custom cache implementation instead. For more details, see [Creating a custom cache](https://github.com/fingerprintjs/fingerprintjs-pro-spa#creating-a-custom-cache)
234-
in the Fingerprint Pro SPA repository (a lower-level Fingerprint library used by this SDK).
235-
- Pass `{ignoreCache: true}` to the `getData()` function to ignore cached results for that specific API call.
236-
237-
> [!NOTE]
238-
> If you use data from [`extendedResult`](https://dev.fingerprint.com/reference/get-function#extendedresult), pay additional attention to your caching strategy.
239-
> Some fields, for example, `ip` or `lastSeenAt`, might change over time for the same visitor. Use `getData({ ignoreCache: true })` to fetch the latest identification results.
240-
241210
## Error handling
242211

243-
The `getData` function throws errors directly from the JS Agent without changing them. See [JS Agent error handling](https://dev.fingerprint.com/reference/error-handling) for more details.
212+
The `getData` function throws errors directly from the JS Agent without changing them. See [JS Agent error handling](https://docs.fingerprint.com/reference/js-agent-v4-error-handling) for more details.
244213

245214
## API Reference
246215

247-
See the full [generated API reference](https://fingerprintjs.github.io/fingerprintjs-pro-react/).
216+
See the full [generated API reference](https://fingerprintjs.github.io/react/).
248217

249218
## Support and feedback
250219

251-
To ask questions or provide feedback, use [Issues](https://github.com/fingerprintjs/fingerprintjs-pro-react/issues). If you need private support, please email us at `oss-support@fingerprint.com`. If you'd like to have a similar React wrapper for the [source-availalbe FingerprintJS](https://github.com/fingerprintjs/fingerprintjs), consider creating an issue in the main [FingerprintJS repository](https://github.com/fingerprintjs/fingerprintjs/issues).
220+
To ask questions or provide feedback, use [Issues](https://github.com/fingerprintjs/react/issues). If you need private support, please email us at `oss-support@fingerprint.com`. If you'd like to have a similar React wrapper for the [source-availalbe FingerprintJS](https://github.com/fingerprintjs/fingerprintjs), consider creating an issue in the main [FingerprintJS repository](https://github.com/fingerprintjs/fingerprintjs/issues).
252221

253222
## License
254223

255-
This project is licensed under the MIT license. See the [LICENSE](https://github.com/fingerprintjs/fingerprintjs-pro-react/blob/main/LICENSE) file for more info.
224+
This project is licensed under the MIT license. See the [LICENSE](https://github.com/fingerprintjs/react/blob/main/LICENSE) file for more info.

__tests__/detect-env.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { detectEnvironment } from '../src/detect-env'
22
import { Env } from '../src/env.types'
3+
import { describe, it, expect } from 'vitest'
34

45
describe('Detect user env', () => {
56
describe('Preact', () => {

__tests__/fpjs-provider.test.tsx

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,36 @@
11
import { useContext } from 'react'
22
import { renderHook } from '@testing-library/react'
3-
import { FpjsContext } from '../src'
3+
import { FingerprintContext } from '../src'
44
import { createWrapper, getDefaultLoadOptions } from './helpers'
5-
import { CacheLocation, FpjsClient, FpjsClientOptions } from '@fingerprintjs/fingerprintjs-pro-spa'
6-
import * as packageInfo from '../package.json'
5+
import { version } from '../package.json'
6+
import { describe, it, expect, vi } from 'vitest'
7+
import * as agent from '@fingerprint/agent'
78

8-
jest.mock('@fingerprintjs/fingerprintjs-pro-spa', () => {
9-
return {
10-
...jest.requireActual<any>('@fingerprintjs/fingerprintjs-pro-spa'),
11-
FpjsClient: jest.fn(() => ({
12-
init: jest.fn(),
13-
})),
14-
}
15-
})
9+
vi.mock('@fingerprint/agent', { spy: true })
10+
11+
const mockStart = vi.mocked(agent.start)
1612

17-
describe(`FpjsProvider`, () => {
18-
it('should configure an instance of the FpjsClient', async () => {
13+
describe('FingerprintProvider', () => {
14+
it('should configure an instance of the Fp Agent', async () => {
1915
const loadOptions = getDefaultLoadOptions()
20-
const options: FpjsClientOptions = {
21-
loadOptions,
22-
cacheLocation: CacheLocation.LocalStorage,
23-
cachePrefix: 'TEST_PREFIX',
24-
cacheTimeInSeconds: 60 * 15,
25-
}
26-
const wrapper = createWrapper(options)
27-
renderHook(() => useContext(FpjsContext), {
16+
const wrapper = createWrapper({
17+
cache: {
18+
cachePrefix: 'cache',
19+
storage: 'sessionStorage',
20+
duration: 100,
21+
},
22+
})
23+
renderHook(() => useContext(FingerprintContext), {
2824
wrapper,
2925
})
30-
expect(FpjsClient).toHaveBeenCalledWith(
31-
expect.objectContaining({
32-
loadOptions: expect.objectContaining({
33-
...loadOptions,
34-
integrationInfo: [`react-sdk/${packageInfo.version}/react`],
35-
}),
36-
cacheLocation: CacheLocation.LocalStorage,
37-
cachePrefix: 'TEST_PREFIX',
38-
cacheTimeInSeconds: 60 * 15,
39-
})
40-
)
26+
expect(mockStart).toHaveBeenCalledWith({
27+
...loadOptions,
28+
integrationInfo: [`react-sdk/${version}/react`],
29+
cache: {
30+
cachePrefix: 'cache',
31+
storage: 'sessionStorage',
32+
duration: 100,
33+
},
34+
})
4135
})
4236
})

__tests__/helpers.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import { PropsWithChildren } from 'react'
2-
import { FpjsClientOptions } from '@fingerprintjs/fingerprintjs-pro-spa'
3-
import { FpjsProvider } from '../src'
4-
import { act } from 'react-dom/test-utils'
2+
import { FingerprintProvider, FingerprintProviderOptions } from '../src'
3+
import { act } from '@testing-library/react'
54

65
export const getDefaultLoadOptions = () => ({
76
apiKey: 'test_api_key',
87
})
98

109
export const createWrapper =
11-
({ loadOptions = getDefaultLoadOptions(), ...options }: Partial<FpjsClientOptions> = {}) =>
12-
({ children }: PropsWithChildren<{}>): JSX.Element => (
13-
<FpjsProvider loadOptions={loadOptions} {...options}>
10+
(providerProps: Partial<FingerprintProviderOptions> = {}) =>
11+
({ children }: PropsWithChildren<{}>) => (
12+
<FingerprintProvider {...getDefaultLoadOptions()} {...providerProps}>
1413
{children}
15-
</FpjsProvider>
14+
</FingerprintProvider>
1615
)
1716

1817
export const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

0 commit comments

Comments
 (0)