Copy-paste patterns for React, Next.js, and Vue 3
publicApiKey to load() to enable usage tracking and higher rate limits.
The snippets below use YOUR_PUBLIC_API_KEY as a placeholder.window, navigator), so it must run
inside useEffect — never at the module or component top level, which would
break during any server-side rendering step.import { useState, useEffect } from 'react'; import { load } from '@mstechmalaysia/helios-fingerprint-sdk'; let heliosFpAgent; function getHeliosFingerprint() { const agentPromise = heliosFpAgent ? Promise.resolve(heliosFpAgent) : load({ publicApiKey: 'YOUR_PUBLIC_API_KEY' }).then(fp => { heliosFpAgent = fp; return fp; }); return agentPromise.then(fp => fp.get()); } export function useFingerprint() { const [result, setResult] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { let cancelled = false; getHeliosFingerprint() .then(data => { if (!cancelled) setResult(data); }) .catch(err => { if (!cancelled) setError(err); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; // cleanup on unmount }, []); return { result, error, loading }; }
import { useFingerprint } from '../hooks/useFingerprint'; export default function FingerprintCard() { const { result, error, loading } = useFingerprint(); if (loading) return <p>Collecting fingerprint…</p>; if (error) return <p>Error: {error.message}</p>; return ( <dl> <dt>Device Core ID</dt> <dd>{result.deviceCoreId}</dd> <dt>Visitor ID</dt> <dd>{result.visitorId}</dd> <dt>VPN</dt> <dd>{result.flags.isVpn}</dd> <dt>Incognito</dt> <dd>{result.flags.isIncognito}</dd> </dl> ); }
window, document, and
navigator — all unavailable on the server. Without a client-side guard your
build will crash. Pick one of the two patterns below.'use client'; // ← required — marks this as a Client Component import { useState, useEffect } from 'react'; import { load } from '@mstechmalaysia/helios-fingerprint-sdk'; let heliosFpAgent; function getHeliosFingerprint() { const agentPromise = heliosFpAgent ? Promise.resolve(heliosFpAgent) : load({ publicApiKey: 'YOUR_PUBLIC_API_KEY' }).then(fp => { heliosFpAgent = fp; return fp; }); return agentPromise.then(fp => fp.get()); } export default function Fingerprint() { const [result, setResult] = useState(null); useEffect(() => { getHeliosFingerprint().then(setResult); }, []); if (!result) return <p>Loading…</p>; return ( <dl> <dt>Device Core ID</dt><dd>{result.deviceCoreId}</dd> <dt>Visitor ID</dt><dd>{result.visitorId}</dd> <dt>VPN</dt><dd>{result.flags.isVpn}</dd> </dl> ); } // Then import it in any Server Component / page: // import Fingerprint from '@/components/Fingerprint'; // <Fingerprint /> — Next.js will automatically render it client-side only
import dynamic from 'next/dynamic'; // ssr: false ensures the component is only ever rendered in the browser const Fingerprint = dynamic( () => import('../components/Fingerprint'), { ssr: false } ); export default function Page() { return ( <main> <h1>My App</h1> <Fingerprint /> </main> ); } // The Fingerprint component itself is the same 'use client' component from Option A
'use client' and drop the component anywhere.
For the Pages Router, use Option B with dynamic(..., {'{'} ssr: false {'}'} ).load() inside onMounted — this guarantees the SDK
only runs in the browser. If you use Nuxt 3, wrap it in onMounted the same way;
do not call it in setup() at the top level.import { ref, onMounted } from 'vue'; import { load } from '@mstechmalaysia/helios-fingerprint-sdk'; let heliosFpAgent; async function getHeliosFingerprint() { if (!heliosFpAgent) { heliosFpAgent = await load({ publicApiKey: 'YOUR_PUBLIC_API_KEY' }); } return heliosFpAgent.get(); } export function useFingerprint() { const result = ref(null); const error = ref(null); const loading = ref(true); onMounted(async () => { try { result.value = await getHeliosFingerprint(); } catch (err) { error.value = err; } finally { loading.value = false; } }); return { result, error, loading }; }
<script setup> import { useFingerprint } from '../composables/useFingerprint'; const { result, error, loading } = useFingerprint(); </script> <template> <p v-if="loading">Collecting fingerprint…</p> <p v-else-if="error">Error: {{ error.message }}</p> <dl v-else> <dt>Device Core ID</dt> <dd>{{ result.deviceCoreId }}</dd> <dt>Visitor ID</dt> <dd>{{ result.visitorId }}</dd> <dt>VPN</dt> <dd>{{ result.flags.isVpn }}</dd> <dt>Incognito</dt> <dd>{{ result.flags.isIncognito }}</dd> </dl> </template>
onMounted
never runs on the server. Do not use useAsyncData or useFetch with
this SDK — those run server-side too.