Embedding the widget
Your study page hands you a ready-made snippet with your own key in it. This page explains what that snippet does, every option you can add to it, and how to make it look like it belongs on your site.
Where to find your snippet
Open the study, stay on the Setup tab, and expand Embed. The examples below use pk_your_study_keyin place of your study’s publishable key.
Inline component
A compact launcher rendered directly into your page, wherever you put the placeholder. Nothing is loaded in an iframe until someone actually starts a conversation, and the chat then opens in a panel over the page.
Drop the <div> where you want the component to appear, then paste the script (anywhere on the page).
<div data-feedback-inline="pk_your_study_key" style="min-height:110px"></div> <script src="https://www.whydeck.com/widget.js" data-study="pk_your_study_key" data-mode="inline" defer></script>
The min-height reserves the launcher's space in plain CSS, before any JavaScript runs, so your page never jumps as the widget loads. Keep it.
Good in a page’s natural flow: under an article, beside a pricing table, at the end of a checkout confirmation. It caps at 480px wide by default and otherwise fills its container.
Floating button
A tab pinned to the edge of the screen on every page you paste it into. Clicking it opens the same chat panel.
Paste it before the closing </body> tag. A “Feedback” tab appears on the edge of the screen.
<script src="https://www.whydeck.com/widget.js" data-study="pk_your_study_key" defer></script>
Position and colours come from the study's style settings — you do not need to re-copy this when you change them.
Good for always-available feedback across a whole app or site. One snippet in a shared layout covers every page at once.
Script attributes
Everything except data-study is optional. The per-page overrides are useful when one study runs in several places and you want it to sit differently in each.
- required
- Your study’s publishable key. Safe to expose — it identifies the study and nothing else. (
data-projectis accepted as an older alias.) - "floating" (default) | "inline"
- Which placement to render. The inline mode also needs the placeholder div.
- inline only · default 480px
- Caps the inline launcher’s width. Any CSS length.
- floating only · default "Feedback"
- Renames the tab.
- floating only
- Overrides the configured position for this page:
right,left,bottom-rightorbottom-left. Anything else falls back to the study’s setting. - floating only
- Overrides the tab’s background colour for this page.
- inline only · "off"
- Goes on the placeholder div, not the script. Ships only a minimal reset so your own CSS owns the launcher entirely.
Styling it from your own CSS
The style settings in the editor cover most cases. When you need to go further, the inline launcher exposes a small set of custom properties. Set them on the placeholder and they win over the study’s saved settings — no !important needed.
[data-feedback-inline] {
--fb-surface: #101014;
--fb-text: #ffffff;
--fb-border: #2a2a33;
--fb-radius: 20px;
}- Card background.
- Text colour.
- Border colour.
- Border width.
- Corner radius.
- Font family.
- Tints hover states. No equivalent setting in the app — it exists so your CSS can retune it.
- Tints the thumbs-down hover state. Same story as
--fb-accent.
For finer control, the launcher exposes ::part() handles — card, prompt, cta and rating-button — so you can target individual pieces. The floating tab is ordinary page markup rather than a shadow root: style it with the .feedback-widget-tab class.
Your CSS cannot leak in by accident
The inline launcher renders in a shadow root, so your site’s stylesheets do not touch it unless you use the properties above. That is deliberate: it means the widget looks the same on every customer page it lands on.
Changing settings later
The snippet carries the key and nothing else. Prompts, placement, colours and the rating type all travel separately, so editing the study updates every page it is already embedded on — you never re-paste to change how it looks or what it asks.
Changes reach live pages within about five minutes, since the configuration is cached at the edge. Your own preview in the app updates immediately.
Single-page apps
If your site is built with React, Vue, Svelte or similar, the widget script has to run afteryour framework has hydrated the page. Load it earlier and the framework may discard the launcher’s markup while reconciling the DOM, so it silently never appears.
In Next.js, use <Script src="/widget.js" strategy="afterInteractive" /> rather than a raw script tag. Other frameworks: mount it from an on-mount effect, or keep it in the static HTML shell outside the app root.
When nothing appears
- Check the browser console.
missing data-study on the script tagmeans the key attribute did not survive the paste. - Is the study ended? An ended study tells the widget to remove itself. Reopen it and the same snippet starts working again.
- Is the key right?Copy it fresh from the study’s Embed section — a truncated key looks plausible and matches nothing.
- Inline mode with no placeholder.
data-mode="inline"needs a matching<div data-feedback-inline="pk_…">on the page. - Hydration, again. On an SPA, this is the most common cause by some distance — see the section above.
- Blocked by an extension or CSP. Ad blockers rarely touch it, but a strict
script-srcwill. Allowhttps://www.whydeck.com.
Next
Once answers start arriving, reading responses covers what you can do with them.