---
title: "Widget modes"
description: "Managed, non-interactive and invisible modes: choose how visible Shield verification is, and configure the widget with data attributes."
url: "https://edge.network/docs/shield/widget-modes"
section: "Shield"
---

# Widget modes

All three modes run the same verification pipeline. The only difference is what the visitor sees. No mode ever shows a puzzle.

## Modes

![The three Shield widget modes as visitors see them](/media/docs/shield-widget-modes.svg)

### Managed (recommended)

Verification is invisible for real users. If the humanity score of a background attempt is low, the widget escalates: it shows a single "I am human" confirmation, and the click triggers a harder proof-of-work challenge. Most visitors never see it.

**Best for:** signup, login and checkout forms, or anywhere you want maximum protection with a human fallback.

### Non-interactive

Background verification with a small status badge ("Verifying… / Verified") so visitors can see protection is active. It never asks for input. Traffic that fails simply doesn't receive a token.

**Best for:** contact forms and comment boxes where a visible trust signal is useful.

### Invisible

No visible widget at all. Verification runs on page load, or on demand via [the JS API](/docs/shield/js-api) (`edgeShield.execute()`). Because there is no visible element, there is no interactive escalation. Low-scoring traffic fails silently.

**Best for:** login pages and SPAs where you want no visible widget and handle low scores server-side.

## Per-widget behaviours

Two further switches sit alongside the mode in the dashboard. They change how verification behaves, not what the visitor sees.

### Shadow mode (report-only)

Nothing is ever blocked: managed mode stops escalating, and [siteverify](/docs/shield/siteverify) always returns success. What strict enforcement *would* have decided is reported in a `shadow` object and counted in analytics.

**Best for:** trialling Shield on production traffic with zero risk of inconveniencing a real customer, then switching enforcement on once the numbers look right.

### Tarpit (on by default)

Clients that keep failing (wrong solutions, too-fast interactive answers, repeated low-score escalations) are served progressively harder proof-of-work. Each repeat offence quadruples the compute cost of the next attempt; one successful verification clears the slate immediately.

Persistent bots pay an exponentially growing electricity bill; a human who stumbles once pays a few hundred extra milliseconds. Disable it per widget if you'd rather repeat failures stay cheap.

## Setting the mode

The mode is configured per widget in the dashboard (**Shield → widget → Settings**) and takes effect on the next challenge issued, with no redeploy needed. You can also override it per placement with `data-mode`:

```html
<!-- Set per-widget in the dashboard, or override per-placement -->
<div class="edge-shield" data-sitekey="es_..." data-mode="invisible"></div>
```

## Data attribute reference

| Attribute | Default | Description |
|---|---|---|
| `data-sitekey` | required | The widget's public sitekey |
| `data-mode` | `managed` | `managed`, `non-interactive` or `invisible` |
| `data-callback` | None | Global function name called with the token on success |
| `data-error-callback` | None | Global function name called with an error string |
| `data-expired-callback` | None | Called when a token expires (the widget auto-refreshes afterwards) |
| `data-input-name` | `edge-shield-response` | Name of the hidden form input the token is written to |
| `data-compat` | None | Set to `turnstile` to also populate a `cf-turnstile-response` input |

## Next steps

- [JavaScript API](/docs/shield/js-api) — Explicit rendering and SPA integration
- [Server-side validation](/docs/shield/siteverify) — The siteverify API and humanity score
