Widgets & Embeds

A widget is the Roast feedback form you install on your website. You create one per site (or one per domain), copy a single script tag, and paste it into your page. This guide covers creating widgets, the install snippet, configuration options, plan limits, and who on your team can manage them.

What a widget is

In Roast, a "widget" and a "form" are the same thing. Each widget is a record (roast_forms) tied to your workspace, with a name, a permitted domain, a submission count, and a JSON settings object that controls how the on-site feedback button looks and behaves.

Every widget has its own ID. That ID is the only thing the install snippet needs: the script reads it, fetches the widget's public settings, and renders the feedback button on your site. Submissions captured by that button are attributed to the widget.

Widgets are owned by the workspace owner. Team members (with the right role) act within the owner's workspace, so the widgets they see and edit belong to the owner, not to their own account.

The widget supports two feedback modes out of the box: Praise (default trigger text "Leave Feedback") and Roast (default "Roast Us 🔥"), the critical-feedback tab with a heat slider.

Submission counts shown next to each widget are a live count of all submissions for that widget.

Creating a widget

Widgets are created from the Embed Code page in the dashboard. Creation requires a name and a domain; the domain is validated server-side.

  1. 1Open the Embed Code page (/dashboard/embed).
  2. 2Click "New Widget" (top right), or "Create your first widget" if you have none yet.
  3. 3Enter a Widget Name (e.g. "My Website"). This is just a label to help you find it later.
  4. 4Enter a Domain. Use a bare hostname like example.com, or * to allow any domain, or localhost (optionally with a port, e.g. localhost:3000) for local testing.
  5. 5Click "Create Widget". The new widget is added to your list and selected automatically, ready with its install snippet.

Domain must be a bare hostname — no https://, no path, no trailing slash. Examples that pass: example.com, app.example.com, *, localhost, localhost:3000. Anything else returns "Invalid domain format".

Creation is gated by role: only Owners and Admins can create widgets (forms:write). Editors and Viewers cannot.

Creation is gated by plan. The free Spark plan allows 1 widget; Flame and Inferno allow unlimited. Hitting the limit returns "Plan limit reached. Upgrade to create more widgets." and the dialog shows an "Upgrade your plan" link to billing.

The plan limit is keyed on the workspace owner's plan, even when an Admin team member creates the widget.

Installing the embed snippet

Once a widget is selected on the Embed Code page, its installation snippet appears under "Installation". It is a single script tag that points at Roast's hosted widget.js and carries your widget's ID in a data attribute.

The snippet looks like this (your app URL and widget ID will be filled in): <script src="https://your-roast-domain/widget.js" data-form-id="YOUR_WIDGET_ID"></script>

The script loads widget.js, reads the data-form-id attribute, fetches that widget's public settings from the API, and renders the floating feedback button on your page.

  1. 1On the Embed Code page, select the widget you want to install from the "Your Widgets" list on the left.
  2. 2Under "Installation", click the copy button next to the snippet (it shows a tick when copied).
  3. 3Paste the snippet into your site's HTML, just before the closing </body> tag.
  4. 4Publish/deploy your site. The feedback button appears at the position configured in the widget's settings.
  5. 5Optional: use the "Preview" panel on the Embed Code page to open a live preview of the widget using its current settings before you ship.

One snippet per widget. To put Roast on a second site, create a second widget so submissions stay separated and the domain matches.

An NPM option is mentioned on the page (npm install @roast/widget) for React/Vue/Angular projects, alongside the script-tag method.

The widget settings endpoint is cached for 5 minutes, so appearance/behaviour changes can take a few minutes to show on a live page.

Configuring a widget

A widget's behaviour and appearance are stored in its settings object. The settings the widget actually reads are: theme (dark/light/auto), accentColor (hex), borderRadius (none/sm/md/lg/full), position (bottom-right/bottom-left/top-right/top-left), trigger text for the Praise and Roast tabs, the prompt questions shown in each mode, feature toggles (video recording, screen recording, Roast mode), branding (the "Powered by Roast" badge and an optional logo), and auto-open triggers.

Auto-open triggers let the widget pop up by itself. The available triggers are: exit intent (mouse leaves toward the browser chrome), scroll depth (fires past a set percentage, 1–100), time on page (fires after N seconds), and rage-click detection (three clicks within a second). There is a master "enabled" switch and a cooldown (in hours, default 24) so a dismissed widget doesn't immediately re-open — the cooldown is remembered in the visitor's browser.

Defaults if you change nothing: dark theme, accent #FF4500, large radius, bottom-right position, all three features (video, screen recording, Roast mode) on, "Powered by Roast" badge shown, and auto-open triggers off.

Settings are saved by PATCHing the widget. Editing settings requires the forms:write permission — Owners and Admins only. Editors and Viewers have read-only access to widgets.

Settings updates are deep-merged: keys you don't send are preserved, so partial updates are safe.

Server-side validation is strict. accentColor must be a 6-digit hex (e.g. #FF4500); scrollDepthPercent must be 1–100; timeOnPageSeconds 1–86400; cooldownHours an integer 0–8760; prompts max 10 items each, 500 chars each; trigger text max 200 chars each. Invalid values are rejected with a specific error message.

Turning OFF the "Powered by Roast" badge (branding.showPoweredBy = false) is plan-gated: it requires the Flame plan or above. On Spark it returns an UPGRADE_REQUIRED error pointing to billing.

The settings the widget receives publicly are restricted to an explicit allowlist, so nothing outside the documented settings is exposed to visitors. If a widget can't be found, the API falls back to default settings so the on-site widget keeps working.

Managing existing widgets

Your widgets are listed on the Embed Code page. Each card shows the widget name, its domain, and its submission count. Selecting a card shows that widget's install snippet and preview.

Each card also has a settings (cog) icon that links to that widget's own configuration screen at /dashboard/widgets/[widgetId]/embed.

Deleting a widget is permanent and removes the widget and its associated data. Deletion requires forms:write (Owners and Admins).

Renaming a widget or changing its domain is also a forms:write action. Name must be 1–100 characters; domain follows the same hostname/wildcard/localhost rules as creation.

The standalone widget configurator screen at /dashboard/widgets/[widgetId]/embed is a richer appearance/behaviour editor (tabs for Appearance, Behaviour, Features, plus device preview and copyable HTML/React snippets). At present this screen is a preview/mock: its controls are not yet wired to save against your real widget, and the snippet it generates uses placeholder values. For a working install snippet, use the Embed Code page (/dashboard/embed).

Wall of Love (testimonial embed)

Separate from the feedback widget, Roast includes a Wall of Love component for displaying collected testimonials (text and video) on a page. It supports four layouts — grid, carousel, masonry, and single featured — and a theme with light/dark mode, accent colour, border radius, and an optional "Collected with Roast" branding link.

Each testimonial card can show a quote, a star rating, the author's name/title/company and avatar, and a video thumbnail that opens the recording in a modal. Video plays inline in a lightbox that closes on Escape or click-outside.

The Wall of Love is a display surface for approved testimonials, not the on-site feedback capture widget — the two are configured separately.

Frequently asked questions

What is the difference between a "widget" and a "form"?
They are the same thing in Roast. The dashboard calls it a widget; internally it is a form record. Each one has its own ID, domain and settings, and is what you install on your site.
How do I install Roast on my website?
Create a widget on the Embed Code page, copy its script snippet, and paste it just before the closing </body> tag of your site. The snippet is a single <script> tag with a data-form-id attribute that loads the widget.
How many widgets can I create?
On the free Spark plan you get 1 widget. Flame and Inferno allow unlimited widgets. If you hit the limit you'll see a "Plan limit reached" message with an upgrade link.
What can I enter as the domain?
A bare hostname like example.com or app.example.com, a single * to allow any domain, or localhost (optionally with a port like localhost:3000) for local testing. Don't include https://, a path, or a trailing slash.
Who on my team can create or edit widgets?
Only Owners and Admins can create, edit, or delete widgets (the forms:write permission). Editors and Viewers can see widgets but cannot change them.
Can I remove the "Powered by Roast" badge?
Yes, but only on the Flame plan or above. On the free Spark plan, attempting to turn it off returns an upgrade-required error pointing to billing.
I changed my widget's appearance but the live site still shows the old look. Why?
The public widget settings are cached for about 5 minutes. Wait a few minutes and reload the page on your site.
What's the difference between the Embed Code page and the per-widget configurator screen?
The Embed Code page (/dashboard/embed) is the working place to create widgets and copy a real install snippet. The per-widget configurator (/dashboard/widgets/[widgetId]/embed) is currently a preview/mock with placeholder values and isn't wired to save settings yet, so use the Embed Code page for installation.
Does deleting a widget remove its submissions?
Deleting a widget is permanent and removes the widget along with its associated data. Only Owners and Admins can delete a widget.