Page code
The contract for a waitlist page's reactCode, for hand-written or agent-generated pages.
A waitlist page is a single JavaScript function rendered in a sandbox with React in scope. You can replace the default template by setting reactCode on create or update, over the REST API or MCP.
The contract
-
One plain function declaration named
GeneratedWaitlist:function GeneratedWaitlist(props) { // ... } -
No JSX, no imports, no TypeScript. Use
React.createElementand hooks through the globalReact(React.useState,React.useEffect, …). Usevarandfunction () {}; avoidconst,let, and arrow functions. -
Style with inline style objects. The page renders full viewport; own the whole background.
-
props.waitlistDatacontains the waitlist’snameanddescription.
Submitting signups
Call props.onSubmit from your form handler:
props.onSubmit({ email: email, name: name || undefined });
Results arrive as window messages. Listen for event.data.type === "waitlist-result":
React.useEffect(function () {
var handler = function (event) {
if (event.data && event.data.type === "waitlist-result") {
if (event.data.success) {
// event.data: { position, alreadyJoined?, referralEnabled?,
// referralCode?, referralCount?, referralBoost?, referralMessage? }
} else {
// event.data.error holds the message
}
}
};
window.addEventListener("message", handler);
return function () {
window.removeEventListener("message", handler);
};
}, []);
Embeds and the content security policy
Waitlist pages run under a strict Content-Security-Policy, because every page is served from the shared usewait.com origin. What that means for your page code:
- Allowed: inline styles and scripts (your
reactCode), images from anyhttpsURL, and iframes from a fixed allowlist of embed hosts — YouTube, Vimeo and Calendly. Frame the plain embed URL directly, for example:https://www.youtube.com/embed/<id>(orhttps://www.youtube-nocookie.com/embed/<id>)https://player.vimeo.com/video/<id>https://calendly.com/<user>/<event>
- Blocked: third-party
<script>tags (including widget loaders like Calendly’swidget.js— use the iframe embed instead),fetch/XHRto any external host, and forms that submit off-site (form-actionis locked to UseWait). Signups go throughprops.onSubmit, not a form action.
If you need a video or a booking widget, drop in the iframe. Anything that needs an external script or posts data to another service will be blocked by the browser.
Turnstile
When props.turnstileEnabled is true the page must render the Cloudflare Turnstile widget. The server rejects any signup without a token, so a form that only prints a “complete the verification” message never submits.
var _t = React.useState(null);
var turnstileToken = _t[0], setTurnstileToken = _t[1];
var turnstileRef = React.useRef(null);
React.useEffect(function () {
if (!props.turnstileEnabled || !props.turnstileSiteKey) return;
if (!document.getElementById("turnstile-script")) {
var sc = document.createElement("script");
sc.id = "turnstile-script";
sc.src = "https://challenges.cloudflare.com/turnstile/v0/api.js";
sc.async = true;
document.head.appendChild(sc);
}
var render = function () {
if (window.turnstile && turnstileRef.current && !turnstileRef.current.hasChildNodes()) {
window.turnstile.render(turnstileRef.current, {
sitekey: props.turnstileSiteKey,
callback: function (t) { setTurnstileToken(t); },
"expired-callback": function () { setTurnstileToken(null); },
theme: "auto"
});
}
};
if (window.turnstile) { render(); }
else {
var i = setInterval(function () {
if (window.turnstile) { clearInterval(i); render(); }
}, 100);
return function () { clearInterval(i); };
}
}, [props.turnstileEnabled, props.turnstileSiteKey]);
Mount the container inside the form, before the submit button, block submit while the token is missing, and pass it to onSubmit:
props.turnstileEnabled && props.turnstileSiteKey
? React.createElement("div", { ref: turnstileRef })
: null
On a custom domain Turnstile is off and props.isCustomDomain is true. Render a hidden honeypot input instead and pass its value as honeypot.
Branding
Free waitlists show a “Made with UseWait” badge. UseWait renders it outside your page code, so do not add your own and do not cover it. It disappears once the waitlist is licensed.
Referral links
When referrals are enabled, build the subscriber’s share link from the referral code in the result payload:
var link =
window.location.origin + window.location.pathname + "?ref=" + referralCode;
Recommended workflow
Create without reactCode
Fetch the current code
GET /api/v1/waitlists/{idOrSlug} (or the get_waitlist MCP tool) returns the live reactCode.Iterate
PATCH it back. The hosted page updates immediately.