Identify your users
Tell Produck who’s giving feedback so each submission ties back to a real user instead of being anonymous. Callidentify once you know who they are — typically right after login.
Pass a login token (JWT)
Already holding the user’s session token? Hand it over and we read the standardsub /
email / name claims for you — one line for Supabase, Auth0, Clerk, Firebase, or Cognito:
Server-rendered pages (no JavaScript)
If your backend already knows the user at render time, setdata-user-* on the script tag and
skip identify entirely. data-user-jwt works the same way if you’d rather pass a token:
Clear identity on logout
Open the widget from your own UI
Wire up your own “Give feedback” button withtrigger:
Fire a campaign trigger
Each trigger on a campaign’s Triggers tab has an id. When the moment it describes happens on your page, fire it, and the widget offers the visitor that campaign’s interview:trigger or the shortcut carries no trigger, even after a
declined offer.
The offer shows even when the page hides the Produck button with data-launcher="none". It then
sits on its own in the bottom-right corner, and once it’s declined or the recording is done the
page shows nothing again.
Listen for events
React when a user submits or dismisses the widget — for example, to show a thank-you toast.Scripted acts
A scripted flow can type into, select and click elements on your page as the visitor answers. Mark each element the script names withdata-produck-target="<name>" — a text field receives,
when the visitor’s answer commits, the value the script judged from their words — never the raw
transcription — typed through its own value setter followed by a bubbling input event, so a
React- or Vue-controlled input sees the change; anything else is clicked. A script can also
signal a marked element instead of clicking it: the widget dispatches a bubbling produck:signal
event on the element with the signal’s name in detail.name, draws the done ring, and leaves
what the signal does to your page. The widget reads the
marked targets at every answer and names what it read in its next acknowledgement. The widget
draws a focus ring on a target a line asks the visitor to use themselves, and a done ring on
every target it fills or clicks. A target
missing from the page is reported on the console and the script carries on.
Bring your own UI
The widget injects two surfaces you can take over. Each is an ownership setting, not a boolean, so it stays meaningful as more options arrive:
Set
none on a surface to suppress the built-in version and render your own. Turning a surface
off never removes capability — trigger, fire, submit, and submit_error keep working. The droplet
is additionally suppressed where the browser cannot record a tab (no display capture, as on
mobile browsers); trigger deliberately still works there, so a custom launcher keeps its
contract.
data-* attributes on the script tag:
config before the script finishes loading, queue it with the same stub shown above for
identify — the widget replays it on boot.
Keep your own Capture Handle
Before a tab recording the SDK tags the page with its own Capture Handle, so it can tell a capture of this very page from a capture of another tab. A page that already sets a handle for a companion capturer — a conferencing app, say — keeps it by declaring it withdata-capture-handle. The SDK then reads that handle and leaves the page’s Capture Handle
configuration alone. List your own origin in the handle’s permittedOrigins, because the SDK
opens its capture from your page.
The keyboard shortcut (⌘/Ctrl + Shift + ?) still opens the widget when
launcher is none — it’s
an invisible trigger, not a visible surface. Rebind it with data-shortcut, or unbind it with
data-shortcut="off", so your launcher is genuinely the only way in — see
Keyboard shortcut.Clean up on logout
Calldestroy to remove the widget when a user’s session ends. On shared devices, this
keeps the next user from seeing the previous one’s identity.