Events and errors
The DOM events the element fires and the error codes onestar:error carries.
The <onestar-feedback> element fires DOM events as the form loads, opens, is answered and closes, and onestar:error when something stops it. Each event's detail names the form and never anything about the person answering.
Listening#
Events bubble and cross the shadow root, so you can listen on the element or on window:
const form = document.querySelector("onestar-feedback");
form.addEventListener("onestar:submit", (e) => {
if (e.detail.final) console.log("Finished", e.detail.form);
});
window.addEventListener("onestar:error", (e) => {
console.warn(e.detail.code, e.detail.message);
});Listen before the form loads (anywhere before or right after the element), so you do not miss onestar:ready or an early onestar:error. For React, Vue and Svelte, see Frameworks.
Events#
| Event | Fires when | detail |
|---|---|---|
onestar:ready | The form loaded and drew for the first time, including a closed form showing its closed message. | { form } |
onestar:open | A popover, slide-in or modal opened. | { form } |
onestar:answer | The person picked or typed an answer. It fires on every change, so on each keystroke in a written answer and each move of a slider. | { form, block } |
onestar:submit | Answers were saved. The widget saves a step at a time, so this fires for each step; final is true only when the person finished the form. | { form, final } |
onestar:close | An overlay closed. | { form } |
onestar:replied | A reply to this person's earlier answer is waiting. | { form, unread } |
onestar:reply | The person answered back in the conversation view inside the form. | { form } |
onestar:error | The form could not show, or an answer could not be saved. | { form, code, message, origin } |
onestar:posted | On a feature board, an idea or comment was posted. state is held while it waits to be checked, else live. | { form, id, state } |
onestar:voted | On a feature board, a vote was cast or taken back. votes is the idea's count now. | { form, id, voted, votes } |
Notes on a few of them:
blockononestar:answeris the question id, the same id the form builder shows.onestar:submitfromonestar.submit()(your own UI) is fired onwindowonly, since there is no element.onestar:repliedcan fire twice for one form: once from the unread check on an overlay's button, and once when the form loads and shows "The makers replied".unreadmay be 0 on the second when the replies were already read.onestar:replyfires from the conversation view inside a form.mode="thread"and<onestar-inbox>do not fire it.originis present only ononestar:errorwithorigin_refused.messageis one plain sentence you may show or log.
Error codes#
onestar:error carries one of these codes. Codes OneStar adds later pass through as they are, so treat an unknown code like server.
| Code | When | What to do |
|---|---|---|
origin_refused | The page's site is not in the form's allowed sites, on load (with origin) or when an answer is sent. The form hides itself; an overlay closes once opened and the popover's tab goes. | Add the origin under Install, Allowed sites. The console names it. |
form_closed | The form is closed, paused, past its closing date or answer limit, not published, or the id is unknown. The form shows its closed message. | Publish or reopen the form, or check the id on its Install tab. |
invalid_form | The form attribute is not a form id: f_ and 16 lower case letters and digits. | Copy the id from the form's Install tab. |
network | The OneStar API did not answer: offline, a connect-src without https://api.onestar.sh, or a blocked request. The form offers Try again, or Retry for an answer. | Check the connection and your Content Security Policy (Allowed sites and security). |
load_failed | The widget code could not load: a script-src without https://embed.onestar.sh, an ad blocker, a proxy. The next open or scroll into view tries again. | Allow https://embed.onestar.sh in script-src. |
identity_required | The form is for signed in users of your product and no token is set, or the token was refused. Fired once each time the form starts asking for a sign in, and the form shows its sign in message. | Call onestar.identify(token) or set user-token (Signed in users). |
stale_form | The form stayed open so long that the token it loaded with expired. The person gets a Reload button. | Nothing; reloading fixes it. |
version_changed | You published a new version while the person was answering. They get a Reload button. | Nothing; reloading shows the new questions. |
too_fast | The answer came sooner after loading than a person could send it. The widget waits a moment and sends it once more before it reports this. | Nothing for a person; a script that sends at once is refused. |
not_found | A later step could no longer be added to the answer, because too long passed since its first step. The person gets a Reload button. | Nothing; the answer saved so far stays. |
rate_limited | Too many requests from this network address, or to this form. The person gets Retry. | Wait and try again. |
server | A failure on OneStar's side. The widget sends the identical answer once more on its own, then shows Retry. | Try again; a retry never counts twice. |
These are not errors and fire nothing, because the form shows them to the person itself:
- An answer the person can fix, such as a missing required answer or a badly typed email. The form shows the message beside the question.
- A second answer to a form that allows one answer per person. The form shows "You already answered this. Thanks."
onestar.submit() rejects with the same codes, plus closed, invalid_answer and already_answered; see Your own UI.
Console messages#
Some problems only you can fix, so the widget also writes one line to the browser console:
| Message | Means |
|---|---|
OneStar: form <id> does not allow <origin>. Add <origin> under Install, Allowed sites in OneStar. | The site is not on the form's allowed list. |
OneStar: form <id> could not load: the OneStar API did not answer. Check the connection, that connect-src allows https://api.onestar.sh, and that <origin> is in the form's allowed sites. | The API could not be reached. |
OneStar: form <id> was not found or is not live. Check the id on the form's Install tab. | The id is wrong, or the form was deleted or never published. |
OneStar: "<value>" is not a form id. Copy it from the form's Install tab. | The form attribute is not shaped like a form id. |
OneStar: the feedback renderer could not load from <url>. Likely causes: a Content Security Policy whose script-src does not allow https://embed.onestar.sh, or a blocked request (an ad blocker, a proxy or firewall, no network). | The widget code was blocked. |
For a form for signed in users with no token, the onestar:error message says: "This form is for signed in users and no user token is set. Call onestar.identify(token) or set user-token."
TypeScript#
To type the events on elements and on window, add this to a .d.ts file:
type OneStarErrorCode =
| "origin_refused" | "form_closed" | "invalid_form" | "network" | "load_failed" | "identity_required"
| "stale_form" | "version_changed" | "too_fast" | "not_found" | "rate_limited" | "server"
| (string & {});
interface OneStarEventMap {
"onestar:ready": CustomEvent<{ form: string }>;
"onestar:open": CustomEvent<{ form: string }>;
"onestar:answer": CustomEvent<{ form: string; block: string }>;
"onestar:submit": CustomEvent<{ form: string; final: boolean }>;
"onestar:close": CustomEvent<{ form: string }>;
"onestar:replied": CustomEvent<{ form: string; unread: number }>;
"onestar:reply": CustomEvent<{ form: string }>;
"onestar:error": CustomEvent<{ form: string; code: OneStarErrorCode; message: string; origin?: string }>;
}
declare global {
interface HTMLElementEventMap extends OneStarEventMap {}
interface WindowEventMap extends OneStarEventMap {}
interface HTMLElementTagNameMap {
"onestar-feedback": HTMLElement;
"onestar-inbox": HTMLElement;
}
}
export {};With it, document.querySelector("onestar-feedback") returns an HTMLElement, and e.detail.final in an onestar:submit listener on it or on window is typed.