---
title: "Shield JavaScript API"
description: "Explicit rendering, programmatic execution, and SPA integration for the Edge Shield widget."
url: https://edge.network/docs/shield/js-api/
---

# Shield JavaScript API

Shield

# JavaScript API

The widget renders implicitly from markup by default, and exposes a small global API for
explicit rendering, SPAs, and on-demand verification.

## Implicit Rendering

With no JavaScript on your side, the script scans for
`.edge-shield[data-sitekey]`
elements on load, renders each one, and appends a hidden
`edge-shield-response`
input to the enclosing form:

```
<script src="https://shield.edge.network/api.js" defer></script>
<div class="edge-shield" data-sitekey="es_..."></div>
```

## Explicit Rendering

For full control, render programmatically. `edgeShield.render()`
returns a widget ID used with the other methods:

```
const widgetId = edgeShield.render(document.getElementById('my-container'), {
  sitekey: 'es_...',
  mode: 'managed',            // optional
  callback: (token) => {      // token issued / refreshed
    submitButton.disabled = false
  },
  errorCallback: (err) => {   // verification failed
    console.warn('shield:', err)
  },
  expiredCallback: () => {    // token expired (auto re-verifies)
    submitButton.disabled = true
  },
})
```

## Methods

```
edgeShield.getResponse(widgetId)  // current token, or null
edgeShield.reset(widgetId)        // clear the token and re-verify
edgeShield.execute(widgetId)      // run verification on demand (invisible mode)
```

| Method | Description |
| `render(el, options)` | Render a widget into a container. Returns a widget ID. Options mirror the data attributes. |
| `getResponse(id?)` | The current token, or `null` if not yet verified. Omit the ID to use the first widget. |
| `reset(id?)` | Clear the current token and run verification again. |
| `execute(id?)` | Run verification on demand — the usual pattern for invisible mode (e.g. just before submit). |

## Single-Page Applications

In an SPA, render explicitly when your form mounts and send the token with your API
request instead of relying on a form post:

```
// React example — render on mount, clean up by resetting
useEffect(() => {
  const id = edgeShield.render(containerRef.current, {
    sitekey: 'es_...',
    callback: setToken,
  })
  return () => edgeShield.reset(id)
}, [])

// Submit the token with your API call
await fetch('/api/signup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, 'edge-shield-response': token }),
})
```

Tokens auto-refresh about a minute before their 5-minute expiry, and the
`callback` fires again with
the fresh token — keep your local copy up to date from the callback rather than caching
the first value.

## Next Steps

[Server-Side Validation Validate tokens from your backend](https://edge.network/docs/shield/siteverify) [Widget Modes Data attributes and mode behaviour](https://edge.network/docs/shield/widget-modes)
[Back to Docs](https://edge.network/docs) [Need help?](https://edge.network/support)
