Skip to main content

Advanced SDK

noscript beacon

When JavaScript is disabled, the snippet never loads. The noscript beacon catches these cases:
<script type="module">
  const mod = await import('https://cdn.shieldlabs.ai/snippet.js?publicKey=YOUR_PUBLIC_KEY');
  mod.checkAnonymous();
</script>
<noscript>
  <img
    src="https://rest.shieldlabs.ai/noscript?publicKey=YOUR_PUBLIC_KEY"
    width="1" height="1"
    style="display:none" alt=""
  >
</noscript>
FieldValue
Score90
DetailsJavaScript disabled (WebRTC) or similar
UserHIDempty / anonymous
DeviceID, VisitorIDzero UUIDs
WebhookFires if callback URL is configured
noscript checks consume request weight like normal fingerprint checks.
Add img-src https://rest.shieldlabs.ai to your CSP if you use the noscript beacon.

Hashing user IDs

Never pass raw user IDs, emails, or phone numbers to checkAuthenticatedUser().
async function hashUserId(userId) {
  const encoder = new TextEncoder();
  const data = encoder.encode(String(userId));
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

const hashedId = await hashUserId(currentUser.id);
mod.checkAuthenticatedUser(hashedId);

Force check patterns

forceCheck* clears sessionStorage and always sends a fresh fingerprint:
document.getElementById('checkout-btn').addEventListener('click', async (e) => {
  e.preventDefault();
  const mod = await import(`https://cdn.shieldlabs.ai/snippet.js?publicKey=${PUBLIC_KEY}`);
  mod.forceCheckAuthenticatedUser(userHashedId, async (ip, requestId) => {
    const response = await fetch('/api/initiate-checkout', {
      method: 'POST',
      body: JSON.stringify({ requestId }),
    });
    if (response.ok) window.location.href = '/checkout';
  });
});

SPA and route changes

Call the SDK once on app initialization. Re-check only when the authenticated user changes:
useEffect(() => {
  (async () => {
    const mod = await import(`https://cdn.shieldlabs.ai/snippet.js?publicKey=${PUBLIC_KEY}`);
    if (user) {
      mod.checkAuthenticatedUser(await hashUserId(user.id));
    } else {
      mod.checkAnonymous();
    }
  })();
}, [user?.id]);
Do not call on every route change unless you intentionally want multiple billable checks.

Port scanning

On Chromium only, the snippet loads portscanner.js and probes localhost ports for antidetect/automation tools. Firefox and Safari skip port scan — TCP OS and STUN signals still apply.

Module caching

Browser import() caches the module URL. Safe to import in multiple places.

WebRTC note

The snippet may POST to /session/{id}/trickle for ICE candidates. Shield.Core uses no-trickle ICE gathering — these requests may 404 without affecting scoring.