File DA-011 View as Markdown
Wix
This page adds Double Agent to a Wix site through Wix's Custom Code setting. It takes a few minutes and no code editing. The last section, for signed form tokens, needs Velo code.
Before you start: Wix runs custom code only on a published site with a connected domain, and connecting a domain needs a Premium plan.
Add the snippet
- In your site's dashboard, go to Settings › Custom Code (under Development & integrations).
- Click + Add Custom Code and paste these two lines. Name it "Double Agent".
<script>window.doubleagent=window.doubleagent||{q:[],push(){this.q.push(arguments)}};</script>
<script async src="https://cdn.doubleagent.so/v1/doubleagent.js" data-profile="auto"></script>
- Under Add Code to Pages, choose All pages and Load code once.
- Under Place Code in, choose Head.
- Open the Code Type tab and choose the category that matches how you use Double Agent. Wix loads Essential code before the visitor answers your cookie banner; the other types wait for consent.
- Click Apply, then publish the site.
Wix adds custom code to the pages on your own domain, so Double Agent sees your visitors' pages. Don't use an Embed HTML element: it runs in a separate frame on a Wix domain.
Check it worked
Custom code doesn't run in the Wix editor or preview, so check the live site on your own domain:
npx @doubleagent-so/cli verify https://your-site.example
It should end with Installed correctly. You can also open the live site, open the browser console and run await doubleagent.ready(). You should see a verdict with class: 'human'.
Wix ties custom code to the site's domain. If you connect a different domain, Wix deletes the snippet, so add it again.
Signed form tokens
A token lets your Wix backend check that a form was sent by a person before it acts on it. You need:
- Your public key in the snippet (
data-key="pk_live_…"afterdata-profile="auto"), and your domain claimed in
Double Agent, because tokens only work from verified domains (Capabilities).
- Your site id (
st_…) from the portal. - A form built from input elements and a button. Wix Forms has no hidden field, so it can't carry the token.
Velo page code runs apart from the page, so it can't call doubleagent itself. A custom element can: on the live site it runs in the page, next to the snippet. It gets the token and hands it to your page code, which sends it to a backend web method. The web method checks the token with Double Agent before it saves anything.
In the editor, click the Code icon and then Start Coding, if coding isn't on yet. Then add three files.
1. The custom element
In Public & Backend, create public/custom-elements/doubleagent-token.js:
<!-- wix:custom-element -->
// Gets a Double Agent token when page code sets the `request` attribute to `<action>:<anything new>`.
class DoubleAgentToken extends HTMLElement {
static get observedAttributes() {
return ['request'];
}
attributeChangedCallback(name, oldValue, request) {
if (!request) return;
const action = request.split(':')[0];
window.doubleagent = window.doubleagent || { q: [], push() { this.q.push(arguments); } };
window.doubleagent.push(async (da) => {
let token = '';
try {
token = await da.getToken(action);
} catch (error) {
// No token: the backend refuses the form.
}
this.dispatchEvent(new CustomEvent('token', { detail: { request, token } }));
});
}
}
customElements.define('doubleagent-token', DoubleAgentToken);
Add it to the page: Add Elements › Embed › Popular Embeds › Custom Element (in Wix Studio, Add Elements › Embed & Social › Custom Element). Click Choose Source, select Velo file, pick doubleagent-token.js and set Tag Name to doubleagent-token. Give it the ID doubleagentToken and make it small; it shows nothing.
2. The backend web method
In Public & Backend, hover over Backend, click + and select Add web module. Name it doubleagent.web.js and put your site id in the third line:
<!-- wix:backend -->
import { Permissions, webMethod } from '@wix/web-methods';
const SITE_ID = 'st_your_site_id';
const REFUSED = ['deny', 'challenge', 'step_up', 'rate_limit'];
async function isPerson(token, action) {
if (typeof token !== 'string' || !token) return false;
const res = await fetch('https://api.doubleagent.so/v1/verify', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ token }),
});
const { valid, claims } = await res.json();
return valid === true && claims.site === SITE_ID && claims.act === action && claims.cls === 'human'
&& !REFUSED.includes(claims.rec) && !claims.integrity?.quarantined;
}
export const submitContact = webMethod(Permissions.Anyone, async (token, values) => {
if (!(await isPerson(token, 'contact'))) return { ok: false };
// Save or send `values` here, for example with the Wix Data API.
return { ok: true };
});
3. The page code
On the form's page, name the inputs email and message, the button send and a text element status. Then add this page code:
<!-- wix:page -->
import { submitContact } from 'backend/doubleagent.web';
$w.onReady(() => {
$w('#doubleagentToken').on('token', async (event) => {
const { ok } = await submitContact(event.detail.token, { email: $w('#email').value, message: $w('#message').value });
$w('#status').text = ok ? 'Thanks, we got your message.' : 'Sorry, that did not go through. Please try again.';
$w('#send').enable();
});
$w('#send').onClick(() => {
$w('#send').disable();
$w('#doubleagentToken').setAttribute('request', `contact:${Date.now()}`);
});
});
Publish and test on your own domain: custom elements run in a frame in the editor and preview, where doubleagent isn't loaded. isPerson is a simple rule; Verify tokens on your server lists every check, including how to let verified agents through.
Next: claim your domain to see your visitors.