-
Notifications
You must be signed in to change notification settings - Fork 26.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding example with-fingerprintjs-pro for identifying visitors (#37549)
## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) Deployed on https://with-fingerprintjs-pro.vercel.app/
- Loading branch information
Showing
22 changed files
with
777 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
NEXT_PUBLIC_FPJS_PUBLIC_API_KEY=<your_fingerprintjs_pro_public_key> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# local env files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# An example app with FingerprintJS Pro | ||
|
||
This example shows how to identify visitors using [FingerprintJS Pro](https://fingerprintjs.com/) with Next.js. | ||
|
||
## Deploy your own | ||
|
||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-fingerprintjs-pro&project-name=with-fingerprintjs-pro&repository-name=with-fingerprintjs-pro) | ||
|
||
## How to use | ||
|
||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: | ||
|
||
```bash | ||
npx create-next-app --example with-fingerprintjs-pro with-fingerprintjs-pro-app | ||
# or | ||
yarn create next-app --example with-fingerprintjs-pro with-fingerprintjs-pro-app | ||
# or | ||
pnpm create next-app --example with-fingerprintjs-pro with-fingerprintjs-pro-app | ||
``` | ||
|
||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). | ||
|
||
## Notes | ||
|
||
### API key | ||
|
||
To identify visitors, you'll need a FingerprintJS Pro account (you can [sign up for free](https://dashboard.fingerprintjs.com/signup/)). | ||
You can learn more about API keys in the [official FingerprintJS Pro documentation](https://dev.fingerprintjs.com/docs/quick-start-guide). | ||
|
||
Once you get public key, you need to set up the API key in the environment variable `NEXT_PUBLIC_FPJS_PUBLIC_API_KEY`. |
27 changes: 27 additions & 0 deletions
27
examples/with-fingerprintjs-pro/components/CacheStrategySelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { useRouter } from 'next/router' | ||
|
||
export const CacheStrategySelector = () => { | ||
const router = useRouter() | ||
const { asPath, route } = router | ||
const value = asPath.split('/')[2] | ||
|
||
return ( | ||
<div className="cache-option-toggler"> | ||
<h4>Cache option</h4> | ||
<select | ||
name="cache-option" | ||
onChange={(event) => { | ||
const newValue = event.currentTarget.value | ||
const newRoute = route.replace('[cacheStrategy]', newValue) | ||
router.push(newRoute, undefined, { scroll: false }) | ||
}} | ||
value={value} | ||
> | ||
<option value="no-cache">Without cache</option> | ||
<option value="memory-cache">Memory Cache</option> | ||
<option value="session-storage-cache">Session Storage Cache</option> | ||
<option value="ls-cache">Local Storage Cache</option> | ||
</select> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { PropsWithChildren } from 'react' | ||
import { useRouter } from 'next/router' | ||
import Link from 'next/link' | ||
import { RouterProps } from './types' | ||
|
||
export const Nav: React.FC = () => { | ||
return ( | ||
<nav className="nav"> | ||
<CustomLink to="home">Home</CustomLink> | ||
<CustomLink to="signin">Sign in</CustomLink> | ||
</nav> | ||
) | ||
} | ||
|
||
const CustomLink: React.FC<PropsWithChildren<{ to: string }>> = ({ | ||
to, | ||
children, | ||
}) => { | ||
const router = useRouter() | ||
const { pathname } = router | ||
const { cacheStrategy } = router.query as RouterProps | ||
const linkPathname = `/${to}/[cacheStrategy]` | ||
const className = `nav-link${pathname === linkPathname ? ' active' : ''}` | ||
return ( | ||
<div> | ||
<Link | ||
href={{ | ||
pathname: linkPathname, | ||
query: { cacheStrategy }, | ||
}} | ||
scroll={false} | ||
> | ||
<a className={className}>{children}</a> | ||
</Link> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { PropsWithChildren, useState } from 'react' | ||
|
||
function Toggler({ children }: PropsWithChildren<{}>) { | ||
const [showChildren, setShowChildren] = useState(true) | ||
|
||
return ( | ||
<div className="toggler"> | ||
<p> | ||
You can open the Network tab in your browser Dev Tools and see new | ||
requests being made depending on the <b>caching algorithm</b> as you | ||
unmount the component with the fingerprint and mount it again thus | ||
calling the <code>useVisitorData</code> hook. | ||
</p> | ||
<button | ||
className="toggle-button" | ||
onClick={() => setShowChildren((show) => !show)} | ||
> | ||
{showChildren ? 'Hide' : 'Show'} visitor data | ||
</button> | ||
{showChildren && children} | ||
</div> | ||
) | ||
} | ||
|
||
export default Toggler |
38 changes: 38 additions & 0 deletions
38
examples/with-fingerprintjs-pro/components/VisitorDataPresenter.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { VisitorData } from '@fingerprintjs/fingerprintjs-pro-react' | ||
|
||
function VisitorDataPresenter({ | ||
data, | ||
isLoading, | ||
error, | ||
}: { | ||
data?: VisitorData | ||
isLoading?: boolean | ||
error?: Error | ||
}) { | ||
if (error) { | ||
return <p>An error occurred: {error.message}</p> | ||
} | ||
|
||
return ( | ||
<div className="visitor-data"> | ||
<p> | ||
<b>Visitor ID:</b>{' '} | ||
{isLoading | ||
? 'Loading...' | ||
: data | ||
? data.visitorId | ||
: 'not established yet'} | ||
</p> | ||
{data && ( | ||
<> | ||
<p> | ||
<b>Full visitor data:</b> | ||
</p> | ||
<pre className="details">{JSON.stringify(data, null, 2)}</pre> | ||
</> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default VisitorDataPresenter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export type CacheStrategyPath = | ||
| 'no-cache' | ||
| 'memory-cache' | ||
| 'session-storage-cache' | ||
| 'ls-cache' | ||
|
||
export type RouterProps = { | ||
cacheStrategy: CacheStrategyPath | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/// <reference types="next" /> | ||
/// <reference types="next/image-types/global" /> | ||
|
||
// NOTE: This file should not be edited | ||
// see https://nextjs.org/docs/basic-features/typescript for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
reactStrictMode: true, | ||
async redirects() { | ||
return [ | ||
{ | ||
source: '/', | ||
destination: '/home/memory-cache', | ||
permanent: true, | ||
}, | ||
] | ||
}, | ||
} | ||
|
||
module.exports = nextConfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start" | ||
}, | ||
"dependencies": { | ||
"@fingerprintjs/fingerprintjs-pro-react": "1.0.1", | ||
"next": "latest", | ||
"react": "18.1.0", | ||
"react-dom": "18.1.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "17.0.40", | ||
"@types/react": "18.0.12", | ||
"typescript": "4.7.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { useRouter } from 'next/router' | ||
import Head from 'next/head' | ||
import '../styles/globals.css' | ||
import '../styles/App.css' | ||
import { InMemoryCache } from '../providers/InMemoryCache' | ||
import { LocalStorageCache } from '../providers/LocalStorageCache' | ||
import { WithoutCache } from '../providers/WithoutCache' | ||
import { SessionStorageCache } from '../providers/SessionStorageCache' | ||
import { CacheStrategySelector } from '../components/CacheStrategySelector' | ||
import { Nav } from '../components/Nav' | ||
import type { AppProps } from 'next/app' | ||
import type { CacheStrategyPath, RouterProps } from '../components/types' | ||
|
||
const getFingerprintJsProProviderByCacheStrategy = ( | ||
cacheStrategy: CacheStrategyPath | ||
) => { | ||
switch (cacheStrategy) { | ||
case 'no-cache': | ||
return WithoutCache | ||
case 'ls-cache': | ||
return LocalStorageCache | ||
case 'session-storage-cache': | ||
return SessionStorageCache | ||
default: | ||
return InMemoryCache | ||
} | ||
} | ||
|
||
function MyApp({ Component, pageProps }: AppProps) { | ||
const router = useRouter() | ||
const { cacheStrategy } = router.query as RouterProps | ||
|
||
const ConfiguredFingerprintJsProProvider = | ||
getFingerprintJsProProviderByCacheStrategy(cacheStrategy) | ||
|
||
return ( | ||
<div className="layout"> | ||
<Head> | ||
<title>FingerprintJs Pro example for Next.js</title> | ||
</Head> | ||
<CacheStrategySelector /> | ||
<main> | ||
<ConfiguredFingerprintJsProProvider> | ||
<Nav /> | ||
<Component {...pageProps} /> | ||
</ConfiguredFingerprintJsProProvider> | ||
</main> | ||
</div> | ||
) | ||
} | ||
|
||
export default MyApp |
38 changes: 38 additions & 0 deletions
38
examples/with-fingerprintjs-pro/pages/home/[cacheStrategy].tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import Toggler from '../../components/Toggler' | ||
import VisitorDataPresenter from '../../components/VisitorDataPresenter' | ||
import { useContext } from 'react' | ||
import { | ||
FpjsContext, | ||
useVisitorData, | ||
} from '@fingerprintjs/fingerprintjs-pro-react' | ||
|
||
function HomePage() { | ||
const { clearCache } = useContext(FpjsContext) | ||
|
||
return ( | ||
<section className="body"> | ||
<h3>Home page</h3> | ||
<div> | ||
On this page we use the <code>useVisitorData</code> hook with default | ||
settings and identification is performed as soon as the page loads. This | ||
is the most common use-case. | ||
</div> | ||
<Toggler> | ||
<VisitorDataComponent /> | ||
</Toggler> | ||
<button className="clear-cache-button" onClick={() => clearCache()}> | ||
Clear cache | ||
</button> | ||
</section> | ||
) | ||
} | ||
|
||
function VisitorDataComponent() { | ||
const { data, isLoading, error } = useVisitorData({ extendedResult: true }) | ||
|
||
return ( | ||
<VisitorDataPresenter data={data} isLoading={isLoading} error={error} /> | ||
) | ||
} | ||
|
||
export default HomePage |
Oops, something went wrong.