Your own UI
Replace the pixels, keep the plumbing. You draw the questions; Respondo still decides what comes next, what may be skipped, and when the answers are sent.
Take the session
Pass onSession and the built-in card never mounts. You get a session instead: read its state, subscribe to changes, and call back with answers.
survey.ts
createRespondo({
key: "rsp_pk_…",
surveyId: "…",
onSession(session) {
session.subscribe(render);
render(session.state());
function render(view) {
if (view.stage === "done") return close();
if (view.stage === "thanks") return thanks(view.thankYou);
// view.question, view.index, view.total
show(view.question, {
// false means required, and the value was blank
onAnswer: (value) => session.answer(value) || flagRequired(),
onSkip: session.skip,
onClose: session.dismiss,
});
}
},
});With the script tag, add data-headless to the tag and hand over a function the same way:
index.html
<script src="https://app.myrespondo.com/embed.js"
data-key="rsp_pk_…"
data-survey="…"
data-headless
defer></script>
<script>
window.Respondo.headless(function (session) {
// the same session as above
});
</script>Session
| Name | Type | What it does |
|---|---|---|
| state() | SessionState | Where the survey is now. See below. |
| subscribe(listener) | () => void | Called after every change. Returns a function that stops it. |
| answer(value) | boolean | Record an answer and move on, following any branch. Returns false without recording when the question is required and the value is blank, so you decide how to say so. |
| skip() | boolean | Move on without answering. False if the question is required. |
| dismiss() | void | Abandon the survey. Answers given so far are still sent. |
| close() | void | Leave the thank-you screen. |
SessionState
| Name | Type | What it does |
|---|---|---|
| stage | "question" | "thanks" | "done" | Asking, showing the thank-you, or finished. |
| question | Question | null | The question on screen, or null once the survey is over. |
| index | number | Its position, for a progress indicator. |
| total | number | How many questions there are. |
| thankYou | ThankYouSettings | null | The title and description to show at the end, if enabled. |
| answers | Answer[] | Everything answered so far. |
| survey | Survey | The whole survey, including its appearance settings. |
What to pass to answer()
| Name | Type | What it does |
|---|---|---|
| nps | number | 0 to 10. |
| rating | number | 1 to the question’s scale — 3, 5 or 7. ratingStyle says whether it was drawn as numbers or faces. |
| choice | string | string[] | The chosen option, or an array of them when multiple is true. allowOther means an “Other” option with free text is allowed. |
| open | string | Free text. placeholder carries the hint written in the editor. |
A blank value — an empty string or an empty array — only counts on a question marked optional.
Keep the attribution
respondo.badge() returns the same “Powered by Respondo” link the built-in card wears, ready to append to your own.
survey.ts
footer.append(respondo.badge({ color: "#71717A" }));