Browser Runtime
This guide explains how the Noxtica SDK operates inside your users’ browsers, including what happens during collection, how caching works, and how to troubleshoot common issues.
How It Works
When you include the Noxtica SDK on your page, it performs these steps:
- Authenticate: Requests a short-lived token using your Site Key
- Collect: Gathers fingerprint signals from browser APIs
- Submit: Sends the fingerprint to Noxtica for scoring
- Cache: Stores the result locally to avoid redundant collections
Your Page → SDK → Token Request → Collect Signals → Submit → Risk Score
↓
Cache (localStorage)
Collection Flow
Automatic (Recommended)
When using data-auto-check-once, the SDK uses smart collection:
<script
src="https://collect.noxtica.com/collector/noxtica-collector.js"
data-site-key="pk_prod_your_site_key"
data-auto-init
data-auto-check-once
async
></script>
First visit: Full fingerprint collection is performed and cached.
Subsequent visits (within TTL): The cached result is returned, and a lightweight visit is recorded. No expensive collection runs.
After TTL expires: A fresh collection is performed.
Manual Control
For programmatic control, use the checkOnce() method:
const client = NoxticaCollector.createClient({
siteKey: 'pk_prod_your_site_key'
});
const result = await client.checkOnce();
if (result.fromCache) {
console.log('Using cached fingerprint');
console.log('Next collection in:', result.nextSubmitIn, 'days');
} else {
console.log('Fresh fingerprint collected');
}
Caching Behavior
The SDK caches fingerprint results in localStorage to minimize redundant collections.
Cache Key
nox_fp_{your_site_key}
What’s Cached
- Device ID
- Last submission timestamp
- Last seen timestamp
- Previous risk score and level
TTL (Time-To-Live)
The default cache TTL is 7 days. This can be configured:
// Override at collection time
const result = await client.checkOnce({
checkIntervalDays: 14 // 14 days instead of 7
});
// Or in seconds
const result = await client.checkOnce({
ttlSeconds: 86400 // 1 day
});
Force Refresh
To bypass the cache and collect a fresh fingerprint:
const result = await client.checkOnce({
forceRefresh: true
});
Cross-Tab Coordination
When a user opens multiple tabs of your site simultaneously, the SDK prevents duplicate fingerprint submissions:
- Only one tab performs the expensive collection
- Other tabs wait and share the result
- Uses Web Locks API (modern browsers) or localStorage fallback
This happens automatically - no configuration needed.
Events
The SDK dispatches events you can listen for:
noxtica:collected
Fired after successful collection or when returning cached result:
document.addEventListener('noxtica:collected', (e) => {
console.log('Fingerprint ID:', e.detail.fingerprintId);
console.log('Risk Level:', e.detail.risk_level);
console.log('Score:', e.detail.score);
console.log('From Cache:', e.detail.fromCache);
});
noxtica:cache-hit
Fired specifically when a cached result is returned:
document.addEventListener('noxtica:cache-hit', (e) => {
console.log('Cache hit, days since submission:', e.detail.daysSinceSubmit);
});
noxtica:error
Fired when collection fails:
document.addEventListener('noxtica:error', (e) => {
console.log('Error source:', e.detail.source);
console.log('Error message:', e.detail.message);
});
Global Variables
After collection, results are available globally:
// After collection completes
console.log(window.noxticaResult);
// Client instance (when using auto-init)
console.log(window.noxticaClient);
// Last error (if any)
console.log(window.noxticaLastError);
Error Handling
Common Errors
| Error | Cause | Solution |
|---|---|---|
origin_mismatch | Site Key doesn’t match your domain | Verify your domain is registered in the Backoffice |
invalid_site_key | Site Key not found or disabled | Check your Site Key and ensure the domain is enabled |
token_expired | Token exceeded 5-minute TTL | Automatic - SDK will request a new token |
| Rate limit (429) | Too many requests | Reduce collection frequency |
Handling Errors Manually
try {
const result = await client.collectAndSubmit();
} catch (error) {
if (error.message.includes('origin_mismatch')) {
// Site key configuration issue
} else if (error.message.includes('rate')) {
// Back off and retry later
}
}
Collection Modes
The SDK supports three collection modes:
| Mode | Description | When to Use |
|---|---|---|
minimal | Basic signals only (Canvas, WebGL, basic info) | Fast collection, low-friction scenarios |
standard | All signals except max-only modules | Most use cases (default) |
max | All signals including WebRTC, speech, keyboard | Maximum accuracy, high-security scenarios |
const client = NoxticaCollector.createClient({
siteKey: 'pk_prod_...',
mode: 'max' // or 'minimal', 'standard'
});
Protected Mode
Noxtica includes an optional protected execution mode that runs collection logic in an isolated WebAssembly sandbox. This provides additional security against tampering.
When enabled, the SDK:
- Loads a secure runtime environment
- Runs collection with additional integrity checks
- Falls back gracefully to standard mode if unavailable
Protected mode is configured server-side and requires no changes to your integration.
Browser Support
The SDK supports modern browsers:
| Browser | Minimum Version |
|---|---|
| Chrome | 70+ |
| Firefox | 65+ |
| Safari | 12+ |
| Edge | 79+ |
Older browsers may have reduced signal accuracy but will still function.
Debug Mode
Enable debug logging to troubleshoot issues:
// Before SDK loads
globalThis.NOXTICA_DEBUG = true;
// Or per-client
const client = NoxticaCollector.createClient({
siteKey: 'pk_prod_...',
debug: true
});
// Or via script attribute
<script src="..." data-debug></script>
Debug mode logs:
- Collection progress
- Token lifecycle
- Cache hits and misses
- Any errors encountered
Note: Debug mode is silent by default in production. No console output appears unless explicitly enabled.
Storage Considerations
localStorage Required
The SDK uses localStorage for caching. If unavailable (private browsing, storage disabled):
- Collection still works
- Every page load performs a fresh collection
- Cross-tab coordination may be reduced
No Cookies
The SDK does not use cookies by default. All state is stored in localStorage.
Performance Impact
First Visit
| Operation | Typical Time |
|---|---|
| Token request | 50-100ms |
| Signal collection | 200-500ms |
| Submission | 50-150ms |
| Total | 300-750ms |
Collection runs asynchronously and doesn’t block page rendering.
Subsequent Visits (Cache Hit)
| Operation | Typical Time |
|---|---|
| Cache check | <1ms |
| Visit recording | 50-100ms |
| Total | 50-100ms |
Troubleshooting
Fingerprint Not Collected
- Check browser console for errors
- Verify Site Key matches your domain exactly (including
https://) - Ensure the domain is enabled in the Backoffice
- Enable debug mode to see detailed logs
Different Device IDs on Same Device
This can happen when:
- localStorage is cleared (user clears browser data)
- Browser profile changes
- Incognito/private browsing mode
- Significant browser updates
This is expected behavior - the fingerprint adapts to device changes.
Collection Taking Too Long
- Check network tab for slow API responses
- Consider using
mode: 'minimal'for faster collection - Ensure the SDK is loaded with
asyncattribute
Events Not Firing
- Ensure you’re listening before the SDK runs
- Check that auto-init attributes are correct
- Verify there are no JavaScript errors blocking execution
Best Practices
-
Use
data-auto-check-onceinstead ofdata-auto-collectto minimize redundant collections -
Load the SDK asynchronously with the
asyncattribute to avoid blocking page load -
Listen for events rather than polling
window.noxticaResult -
Don’t override the TTL unnecessarily - the default 7-day interval is optimized for most use cases
-
Handle errors gracefully - collection failure shouldn’t break your page
Next Steps
- Getting Started - Initial setup guide
- Backend Integration - Server-side device lookups