Deck Docs
SDKs

Feedback Widget SDK

Embed @deck/feedback widgets so in-product feedback flows into Deck.

Feedback Widget SDK

The Feedback Widget SDK (@deck/feedback) lets you embed feedback collection in your product. Submissions land in Deck as a first-class source, appear under Manage → Widgets, and can be synthesized into insights and themes.

Use this when you want customers to share feedback without leaving your app — for example after a new feature, on a settings page, or next to an AI response.

Feedback Widgets is rolling out. The in-product widget setup pages are disabled by default, and @deck/feedback is not yet published to npm. You may not see Manage → Widgets or Settings → Feedback Widget SDK, and external apps cannot install the package until Deck enables and publishes the feature.

What you need

  1. A widget in Deck (identifies the source of feedback)
  2. A publishable key (pk_…) for client-side auth
  3. The @deck/feedback React package in your app
ItemWhere to create itSafe in the browser?
Widget ID (wgt_…)Manage → WidgetsYes (public identifier)
Publishable key (pk_…)Settings → Feedback Widget SDKYes (client-safe; scoped to widget ingest)
Secret API key (dk_…)Settings → Deck APINo — not for this SDK

Publishable keys are for the widget SDK only. They cannot call the Deck Public API. Use secret dk_… keys for server-side Public API access.

Setup in Deck

1. Create a feedback widget

  1. Go to Manage → Widgets
  2. Click Create widget
  3. Give it a clear name (for example “Settings panel” or “AI message”)
  4. Copy the widget ID from the widget detail page

Optionally link the widget to a Project so submissions can attach as Project Evidence when free-text is present.

2. Create a publishable key

  1. Go to Settings → Feedback Widget SDK
  2. Create a publishable key
  3. Copy the full pk_… secret immediately — Deck only shows it once
  4. Store it in your app’s environment (for example NEXT_PUBLIC_DECK_PUBLISHABLE_KEY)

You can use one publishable key across multiple widgets in the same organization.

3. Install the package after it is published

pnpm add @deck/feedback
# or
npm install @deck/feedback

Peer dependencies: react and react-dom (18+).

Quick start

Wrap your product UI in DeckProvider, then use built-in widgets or your own UI.

import { useState } from "react";
import {
  DeckProvider,
  FeedbackDialog,
  ThumbsFeedback,
} from "@deck/feedback";

function App() {
  return (
    <DeckProvider
      publishableKey={process.env.NEXT_PUBLIC_DECK_PUBLISHABLE_KEY!}
      user={{
        id: currentUser.id,
        email: currentUser.email,
        name: currentUser.name,
      }}
    >
      <ProductUi />
    </DeckProvider>
  );
}

function ProductUi() {
  const [open, setOpen] = useState(false);

  return (
    <>
      {/* You own the trigger button */}
      <button type="button" onClick={() => setOpen(true)}>
        Share feedback
      </button>
      <FeedbackDialog
        widgetId="wgt_your_widget_id"
        open={open}
        onOpenChange={setOpen}
        context={{ surface: "settings" }}
      />

      {/* Built-in thumbs; opens the dialog with sentiment pre-set */}
      <ThumbsFeedback
        widgetId="wgt_your_widget_id"
        context={{ messageId: "msg_123" }}
      />
    </>
  );
}

Replace wgt_your_widget_id with the ID from Manage → Widgets.

Components

DeckProvider

Required root. Passes auth and user identity to child widgets.

PropRequiredDescription
publishableKeyYesYour pk_… key
userRecommendedAt least id; optional email, name for contact matching
headlessNoSkip Deck theme wrapper when you fully own the UI
apiUrlNoOverride ingest URL (defaults to Deck production)

FeedbackDialog

Controlled modal for written feedback. Your app owns the open/close trigger.

ThumbsFeedback

Like / dislike controls that open the dialog with sentiment pre-filled.

Headless submit

Build your own form and submit through the SDK:

import {
  DeckProvider,
  useSubmitFeedback,
} from "@deck/feedback";

function MyFeedbackForm() {
  const { submitFeedback, isSubmitting, lastError } = useSubmitFeedback();

  async function onSubmit(message: string) {
    const result = await submitFeedback({
      widgetId: "wgt_your_widget_id",
      sentiment: "positive",
      message,
      context: { surface: "settings" },
    });

    if (result.ok) {
      // close modal, toast, etc.
    }
  }

  // render your own UI…
}

Wrap headless UIs in DeckProvider (optionally with headless).

User identity

Pass a stable product user id on DeckProvider:

user={{
  id: currentUser.id, // required for reliable identity
  email: currentUser.email,
  name: currentUser.name,
}}

Deck uses this to attribute submissions and match contacts when possible. Prefer the same id you use elsewhere in your product.

Optional context

context is a free-form object stored with the submission (for example surface name, message id, or feature flag). Use it to filter or debug later in Deck.

context={{ surface: "intelligence-panel", messageId: "msg_123" }}

Where feedback goes in Deck

  1. User submits from your product via @deck/feedback
  2. Deck stores a raw submission under Manage → Widgets → [your widget]
  3. When free-text is present, Deck synthesizes the submission into insights (uses organization credits)
  4. Insights appear in Visualize (themes, categories, etc.)
  5. If the widget is linked to a Project, evidence can attach to that Project when synthesis runs

Submissions without a message stay raw (no synthesis).

Install snippet in the product

Deck also shows an install snippet in:

  • Settings → Feedback Widget SDK
  • Manage → Widgets → [widget] (until the widget has submissions)

Use those pages for copy-paste setup while integrating.

Security notes

  • Do embed publishable keys (pk_…) in client apps
  • Do not put secret Public API keys (dk_…) in the browser or in @deck/feedback
  • Revoke a publishable key from Settings → Feedback Widget SDK if it is exposed beyond your control; widgets using that key will stop accepting submissions
  • Prefer environment variables (for example NEXT_PUBLIC_DECK_PUBLISHABLE_KEY) so keys are not hard-coded

Troubleshooting

SymptomWhat to check
Submissions never appearWidget ID and publishable key belong to the same Deck org
401 / unauthorizedKey revoked, mistyped, or not a pk_… publishable key
No insights after submitMessage body empty (raw only), or org out of credits
Wrong product surfaceConfirm widgetId and optional context on the component