Next.js Integration
Integrate FingerprintIQ with Next.js App Router.
Installation
bashnpm install @fingerprintiq/js
bashyarn add @fingerprintiq/js
bashpnpm add @fingerprintiq/js
FingerprintIQ uses browser APIs (canvas, WebGL, audio context) and cannot run in Server Components. Any component that uses the SDK must be marked with 'use client'.
Using the built-in hook
For most apps, the built-in Next.js hook is the fastest path:
tsx// components/visitor-gate.tsx'use client';import { useFingerprintIQ } from '@fingerprintiq/js/next';export function VisitorGate() { const { result, loading, error } = useFingerprintIQ({ apiKey: process.env.NEXT_PUBLIC_FIQ_API_KEY!, }); if (loading) return <p>Identifying…</p>; if (error) return <p>Error: {error.message}</p>; return <p>Visitor: {result?.visitorId}</p>;}
The /next subpath ships with "use client"; baked in, so you can import it from any file and only mark your own wrapper component as a client component. Under the hood it re-exports the same hook as @fingerprintiq/js/react — choose whichever import path you prefer.
If you need a custom wrapper (e.g. to integrate with your auth flow or route changes), see the "Custom hook" pattern below.
Client-Side Identification
Create a reusable hook in a client component:
tsx// components/Fingerprint.tsx'use client';import { useEffect, useRef, useState } from 'react';import FingerprintIQ from '@fingerprintiq/js';export function useFingerprint() { const [visitorId, setVisitorId] = useState<string | null>(null); const [botProbability, setBotProbability] = useState<number | null>(null); const fiqRef = useRef<FingerprintIQ | null>(null); useEffect(() => { async function init() { if (!fiqRef.current) { fiqRef.current = new FingerprintIQ({ apiKey: process.env.NEXT_PUBLIC_FIQ_API_KEY!, }); } const result = await fiqRef.current.identify(); setVisitorId(result.visitorId); setBotProbability(result.botProbability); } init().catch(console.error); }, []); return { visitorId, botProbability };}
Server-Side Verification
After identifying on the client, send the visitorId to your API route for verification. This prevents spoofed visitor IDs from bypassing your trust logic.
typescript// app/api/verify/route.tsimport { NextResponse } from 'next/server';export async function POST(req: Request) { const { visitorId } = await req.json(); const res = await fetch( `https://fingerprintiq.com/v1/demo/visits/${visitorId}`, { headers: { 'X-API-Key': process.env.FIQ_SECRET_KEY!, 'Content-Type': 'application/json', }, } ); const data = await res.json(); const isLegitimate = data.totalVisits >= 1 && data.visits[0]?.confidence >= 0.8 && data.visits[0]?.botProbability < 0.3; return NextResponse.json({ verified: isLegitimate, isReturning: data.totalVisits > 1, firstSeen: data.firstSeenAt, totalVisits: data.totalVisits, });}
Environment Variables
env# .env.localNEXT_PUBLIC_FIQ_API_KEY=fiq_live_your_public_keyFIQ_SECRET_KEY=fiq_live_your_secret_key
Never expose your secret API key to the client. The NEXT_PUBLIC_ prefix makes variables available in the browser — only use it for your public key. The secret key must stay server-side only.
Full Integration Example
Putting it all together — identify on the client, verify on the server, gate a feature:
tsx// app/checkout/page.tsx'use client';import { useEffect } from 'react';import { useFingerprint } from '@/components/Fingerprint';export default function CheckoutPage() { const { visitorId, botProbability } = useFingerprint(); useEffect(() => { if (!visitorId) return; // Send to your server for verification fetch('/api/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ visitorId }), }) .then(res => res.json()) .then(data => { if (!data.verified) { // Redirect or show challenge window.location.href = '/verify'; } }); }, [visitorId]); if (botProbability !== null && botProbability > 0.7) { return <div>Access denied. Suspicious activity detected.</div>; } return <CheckoutForm />;}
Add FingerprintIQ identification to your root layout so the visitor ID is available by the time users reach protected pages — avoiding a waterfall of identify → verify → render.