Installation

bash
npm install @fingerprintiq/js

@fingerprintiq/js ships a React hook at @fingerprintiq/js/react. Use it directly, or build your own wrapper with the patterns below.

Using the built-in hook

For most apps, the built-in hook is enough:

tsx
import { useFingerprintIQ } from '@fingerprintiq/js/react';function Component() { const { result, loading, error, identify } = useFingerprintIQ({ apiKey: 'fiq_live_...', }); if (loading) return <p>Identifying…</p>; if (error) return <p>Error: {error.message}</p>; return <p>Visitor: {result?.visitorId} · Bot score: {result?.botProbability}</p>;}

The hook:

  • Instantiates the client once per component via useRef
  • Auto-calls identify() on mount (pass manual: true to opt out)
  • Exposes loading, error, and an identify() function for manual re-fetches
  • Is safe in React Strict Mode

If you need custom lifecycle behavior, build your own wrapper using the pattern below.

The useFingerprintIQ Hook

Build a reusable hook that wraps the SDK. Using useRef ensures the FingerprintIQ instance is created only once per component tree, even in React Strict Mode.

tsx
import { useRef, useState } from 'react';import FingerprintIQ from '@fingerprintiq/js';interface FingerprintIQResult { visitorId: string; visitCount: number; confidence: number; botProbability: number; riskFactors: string[];}function useFingerprintIQ(apiKey: string) { const [result, setResult] = useState<FingerprintIQResult | null>(null); const [loading, setLoading] = useState(false); const [error, setError] = useState<Error | null>(null); const fiqRef = useRef<FingerprintIQ | null>(null); if (!fiqRef.current) { fiqRef.current = new FingerprintIQ({ apiKey }); } const identify = async () => { setLoading(true); setError(null); try { const res = await fiqRef.current!.identify(); setResult(res); return res; } catch (err) { setError(err as Error); throw err; } finally { setLoading(false); } }; return { identify, result, loading, error };}

Usage in Components

tsx
import { useEffect } from 'react';function LoginPage() { const { identify, result, loading, error } = useFingerprintIQ( process.env.NEXT_PUBLIC_FIQ_API_KEY! ); useEffect(() => { identify(); }, []); if (loading) return <p>Identifying device...</p>; if (error) return <p>Fingerprint unavailable</p>; return ( <div> <p>Visitor ID: {result?.visitorId}</p> <p>Visit count: {result?.visitCount}</p> {result?.botProbability > 0.5 && ( <p>⚠️ Suspicious activity detected</p> )} </div> );}

Call identify() as early as possible in the page lifecycle — ideally in a root layout or useEffect at the app level. This gives the SDK time to collect all signals before the user interacts with protected features.

Context Provider Pattern

For larger applications, expose fingerprint data via React Context to avoid prop drilling:

tsx
// contexts/FingerprintContext.tsximport { createContext, useContext, useEffect, useRef, useState } from 'react';import FingerprintIQ from '@fingerprintiq/js';const FingerprintContext = createContext(null);export function FingerprintProvider({ children, apiKey }) { const [fingerprint, setFingerprint] = useState(null); const fiqRef = useRef(null); useEffect(() => { if (!fiqRef.current) { fiqRef.current = new FingerprintIQ({ apiKey }); } fiqRef.current .identify() .then(setFingerprint) .catch(console.error); }, [apiKey]); return ( <FingerprintContext.Provider value={fingerprint}> {children} </FingerprintContext.Provider> );}export const useFingerprint = () => useContext(FingerprintContext);
tsx
// app/layout.tsx or _app.tsximport { FingerprintProvider } from '@/contexts/FingerprintContext';export default function RootLayout({ children }) { return ( <FingerprintProvider apiKey={process.env.NEXT_PUBLIC_FIQ_API_KEY}> {children} </FingerprintProvider> );}

With Next.js App Router

FingerprintIQ requires browser APIs and cannot run in Server Components. Mark any component using the SDK with 'use client'.

tsx
// components/FingerprintProvider.tsx'use client';import { useEffect, useRef } from 'react';import FingerprintIQ from '@fingerprintiq/js';export function FingerprintProvider({ children }: { children: React.ReactNode }) { const fiqRef = useRef<FingerprintIQ | null>(null); useEffect(() => { if (!fiqRef.current) { fiqRef.current = new FingerprintIQ({ apiKey: process.env.NEXT_PUBLIC_FIQ_API_KEY!, }); } fiqRef.current.identify().catch(console.error); }, []); return <>{children}</>;}