Put your board on your own website
One script tag embeds your feedback board anywhere — inline in a page, or as a floating bubble that opens a popover and expands to full page. Members vote and post without leaving your site, and without creating an account.
Settings turn on Public board so the board is reachable at all, and Allow anonymous so visitors can vote and post. With the second one off the board still renders, but it is read-only — scores show as plain numbers instead of buttons. Public boards are on every plan, including Free.Which mode do I want?
| Inline | The board renders in the page, where you put the script tag. Best for a dedicated /feedback or /roadmap page. |
| Launcher | A floating bubble in the corner opens the board in a popover. Best for putting feedback one click away on every page. |
| Your own trigger | No bubble — your existing nav link or button opens it. Best when you already have a “Feedback” entry point. |
| Direct link | No embed at all: just link to your board URL. Best for emails, changelogs and social posts. |
Inline embed
Drop this where you want the board to appear. It inserts an iframe in place — nothing else on the page is touched.
<script src="https://quillboard.xyz/widget.js"
data-board="your-board-slug"></script>Set data-height to change the starting height (default 600px).
Launcher (floating bubble)
Adds a bubble in the bottom corner. Clicking it opens the board in a popover with controls to expand it to full page, pop it out to a new tab, or close it.
<script src="https://quillboard.xyz/widget.js"
data-board="your-board-slug"
data-mode="launcher"></script>Paste it once, ideally just before </body>, and it works on every page it is included on. Customise it with data-position, data-label and data-accent.
Use your own button or link
If you already have a “Feedback” link, point the widget at it with a CSS selector and hide the bubble. No JavaScript needed on your side.
<a id="feedback-link" href="#">Feedback</a>
<script src="https://quillboard.xyz/widget.js"
data-board="your-board-slug"
data-mode="launcher"
data-trigger="#feedback-link"
data-bubble="0"></script>The selector may match several elements — a nav link and a footer link can both open the same board. Leave data-bubble off if you want the floating button as well.
JavaScript SDK
In launcher mode the widget exposes a small global so you can drive it from your own code — open the board from an empty state, after a failed search, or at the end of a checkout.
Quillboard.open() // open the popover
Quillboard.close() // close it
Quillboard.toggle() // open if closed, close if open
Quillboard.expand() // open and expand to full page
Quillboard.collapse() // back to the popover
Quillboard.isOpen() // -> boolean
Quillboard.boardUrl() // -> shareable board URL (not the embed variant)All options
| data-board | Required. Your board slug — the last part of your board URL. |
| data-mode | inline (default) or launcher. |
| data-height | Inline height in px. Default 600. Ignored in launcher mode. |
| data-position | bottom-right (default) or bottom-left. |
| data-label | Bubble text. Default “Feedback”. Markup is stripped. |
| data-accent | Bubble colour — any CSS colour. Default #6366f1. |
| data-trigger | CSS selector for your own opener element(s). |
| data-bubble | 0 hides the floating bubble. Use with data-trigger. |
| data-open | 1 opens the panel on page load. |
| data-sso | A signed JWT so posts and votes carry your real user. See below. |
| data-origin | Point at a self-hosted instance. Auto-detected from the script URL otherwise. |
SSO — post as your real users
By default web visitors participate anonymously. If you already know who they are, sign a short-lived JWT with your board’s SSO secret and hand it to the widget — votes, posts and follows are then attributed to that person, and they can be recognised across devices.
<script src="https://quillboard.xyz/widget.js"
data-board="your-board-slug"
data-mode="launcher"
data-sso="<jwt-your-backend-signed>"></script>- 1Under
Settings → Embeddable widget & SSO, turn SSO on and set a shared secret (at least 16 characters). You choose this value — keep it server-side only. - 2On your server, sign a JWT containing the user’s id (and optionally name and email). Never sign in the browser — the secret would be exposed.
- 3Render the token into the script tag for that request.
- 4The widget forwards it to the board, which exchanges it for a first-party session inside the iframe.
Custom domain
On Scale you can serve the board from your own hostname — for example feedback.yourcompany.com — instead of embedding it. The root of that domain then serves your board with no Quillboard URL visible. Combine it with white-label branding (your logo, accent colour and name) for a board that reads entirely as your product.
- 1Enter the hostname under
Settings → Custom domainand pressSave domain. - 2Press
Verify. ATXTrecord is shown — add it at your DNS provider to prove you own the domain, then pressVerifyagain. - 3Once verified, point the hostname at
quillboard.xyzwith aCNAMEto go live.
How the widget behaves
| Style isolation | Everything injected lives in a shadow root, so your CSS cannot restyle the widget and the widget cannot leak styles into your page. |
| Cookies | The board runs on our origin inside the iframe, so its cookies stay first-party — anonymous and SSO participation work without third-party-cookie or CORS problems. |
| Loading | The board is fetched on first open, not on page load. |
| Keyboard | Esc steps back one level: full page → popover → closed. Focus returns to the bubble on close. |
| Screen readers | The bubble is an aria-haspopup="dialog" button with live aria-expanded; the panel is a labelled dialog, and announces itself modal only while expanded. |
| Mobile | Below 520px the popover becomes a full-screen sheet automatically. |
| Motion | Transitions are dropped under prefers-reduced-motion. |
| Framing | Only the public board may be framed. Every other page sends frame-ancestors none, so the dashboard can never be embedded. |
Self-hosting
The widget derives our origin from its own script URL, so a self-hosted instance works with no extra configuration — serve /widget.js from your deployment and it points at itself. Only if you copy the file onto your own domain do you need to say where the board lives:
<script src="/vendor/widget.js"
data-board="your-board-slug"
data-origin="https://feedback.yourcompany.com"></script>Troubleshooting
| Nothing appears | Check the browser console. A missing data-board logs an explicit error and the widget renders nothing rather than throwing into your page. |
| “Board not found” | Public board is off in Settings, or the slug is wrong. The message is deliberately vague so it never confirms whether a community exists. |
| Scores show but nothing is clickable | Allow anonymous is off — the board is read-only by design. Turn it on in Settings. |
| My own link does nothing | Confirm data-trigger is a valid CSS selector and the element exists when the script runs. An invalid selector logs a warning and leaves the bubble working. |
| Posts are anonymous | Expected without data-sso. Sign a token server-side to attribute them. |
Related
Pushing status changes out to Slack, GitHub, Linear or Jira, adding the bots in Discord or Telegram, or moderating what arrives — see the admin guide.