Browser Runtime
This guide explains how the Noxtica SDK works inside your visitors’ browsers — what happens during an assessment, how caching keeps things fast, and how to troubleshoot common issues.
How It Works
When you add the Noxtica SDK to your page, it quietly does four things:
- Authenticate: Signs in with your Site Key using credentials it manages for you
- Collect: Reads the everyday signals a browser already exposes
- Submit: Sends them to Noxtica for scoring
- Cache: Stores the result locally so it doesn’t repeat the work on every visit
All of this runs in the background and never blocks your page.
Collection Flow
Automatic (Recommended)
When using data-auto-check-once, the SDK uses smart collection:
<script
src="https://collect.noxtica.com/collector/noxtica.js"
data-site-key="pk_prod_your_site_key"
data-auto-init
data-auto-check-once
async
></script>
Using a content-security-policy? You’ll need to allow Noxtica to load and run its tamper-resistant runtime, the KHAN VM. If it can’t, Noxtica keeps working with a lighter form of collection and weaker tamper protection. See Getting Started → Content Security Policy for the exact snippet.
First visit: A full assessment runs and the result is cached.
Subsequent visits (within the cache window): The cached result is returned and a lightweight visit is recorded. No heavy work runs.
After the cache window expires: A fresh assessment runs.
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 each result in the browser so it doesn’t reassess the same visitor on every page view.
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 visitor opens several tabs of your site at once, the SDK makes sure they’re only assessed once:
- Only one tab does the real work
- The other tabs wait and share that result
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 | A small core set of signals | Fast collection, low-friction scenarios |
standard | A broad set of signals | Most use cases (default) |
max | The full set of signals | Maximum accuracy, high-security scenarios |
const client = NoxticaCollector.createClient({
siteKey: 'pk_prod_...',
mode: 'max', // or 'minimal', 'standard'
});
Protected Mode (KHAN VM)
The hardest part of fighting bots is that anything running in a browser is, in principle, visible and editable. A determined attacker can read the page’s code, figure out what’s being measured, and quietly feed back fake answers.
The KHAN VM raises the cost of that. Instead of leaving collection out in the open as readable code on the page, Noxtica runs the sensitive part inside a sealed, sandboxed runtime. The logic that decides what to measure isn’t sitting in plain sight for an attacker to study and rewrite, and the result it produces is sealed before it leaves the browser — so it’s far harder to tamper with or replay.
What the KHAN VM helps with:
- Tamper-resistant results — the assessment is sealed inside the sandbox before it’s sent, so other scripts on the page can’t quietly alter or replay it.
- Harder to reverse-engineer — the collection logic stays hidden inside the runtime instead of being readable in the browser’s developer tools.
- Replay protection — each result is one-time and verified, so a captured response can’t simply be reused to fake a clean visitor.
Honest limits — what it does not do:
- It is a tamper-resistance feature, not end-to-end encryption.
- If your own page is compromised (for example, by a cross-site scripting flaw), an attacker on that page can see the same raw browser signals that Noxtica sees. The KHAN VM protects the processing and the result, not the page around it.
The KHAN VM is turned on from the server side and needs no changes to your integration. If it can’t start — for example, because a content-security-policy blocks it — Noxtica falls back to a lighter form of collection so detection keeps working, just with weaker tamper protection.
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
Browser Storage
The SDK uses the browser’s local storage to cache results. If that’s unavailable (for example, in private browsing or with storage disabled):
- Detection still works
- Every page load runs a fresh assessment
- Cross-tab coordination may be reduced
No Cookies
The SDK doesn’t use cookies. Everything it needs is kept in the browser’s local storage.
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
”WebAssembly blocked by Content Security Policy”
If you see this warning in the browser console, your page’s content-security-policy is blocking the tamper-resistant runtime (the KHAN VM). Detection keeps working in a lighter mode, but you’ll get the strongest protection by allowing it.
Use the snippet below to allow Noxtica to load and run:
Content-Security-Policy: script-src 'self' 'wasm-unsafe-eval' https://collect.noxtica.com; connect-src 'self' https://collect.noxtica.com
See Getting Started → Content Security Policy for the full reference.
Different Device IDs on Same Device
This can happen when:
- The browser’s stored data is cleared
- The browser profile changes
- The visitor uses private/incognito mode
- The browser goes through a major update
This is expected — the recognition adapts as a device changes over time.
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