Custom JavaScript runs in a tightly scoped environment. This page lists everything the runtime blocks today (and why), so authors don't waste time chasing features that won't ever ship.
Blocked globals#
The builder's script validator and the runtime sandbox both shadow these globals. Referencing them in custom JS produces a builder warning today and will throw inside the sandbox once it ships:
| Global | Why blocked |
|---|---|
window | Bypasses the API surface — use Intuify.survey.*. |
document | DOM mutations break the engine's render contract. |
localStorage | Persistent data must go through setVariable. |
sessionStorage | Same — use survey variables. |
fetch | External calls belong on Web Service flow blocks. |
XMLHttpRequest | Same. |
eval | Defeats the sandbox. |
Function | Same. |
parent, top | Prevents script-driven iframe escapes. |
frames | Same. |
opener | Same. |
The full list lives in src/lib/script-validation.ts and is kept in
sync with the runtime sandbox so the builder warns about anything that
will fail at runtime.
What custom JS can do#
- Read and write the survey's variables (
setVariable,getVariable). - Read the current question, its choices/rows/columns, and the resolved text.
- Read and write any answer on the current page through
setResponse. - Read URL query parameters captured at session start.
- Resolve piped tokens against the current snapshot.
- Inspect plugin payloads (
getQuestionPayload) for migration / debug work.
What custom JS cannot do (phase 1)#
- Navigate the survey (
advance/goBack/terminateland with the sandbox). - Mutate the DOM directly.
- Call external services.
- Read or write other respondents' data.
- Persist anything across sessions.
- Override server-side variables in the server-driven respondent runtime (writes are no-ops there today; reads still work).
Security expectations#
- Treat custom JS as untrusted input the same way you would treat embedded HTML. Don't paste scripts you don't fully understand.
- The sandbox enforces a hard timeout to prevent runaway loops.
- Scripts can't escape into the survey builder UI or other open tabs.
- All runtime data exposed (questions, choices, variables, URL params) is already visible to the respondent — the API doesn't widen the attack surface, it just makes that data easier to consume.
When to use Web Service blocks instead#
If you need to call an API, log to an analytics endpoint, or fetch external data, use a Web Service flow block. Those run on the server during navigation, can authenticate with API keys, and feed results back into the engine as variables — none of which custom JS is allowed to do.
Use custom JS only for read/transform/write on the survey state itself; everything else belongs in the flow editor.
Related guides#
- Custom JS overview
- API reference
- Examples
- Flow editor — for Web Service blocks and other server-side integrations.
Was this page helpful?