1. Allow your site’s origin
Tell the Engine which origins may connect from a browser, with theTHREADIFY_BROWSER_ORIGINS environment variable:
http:// is only accepted for
localhost during development.
2. Issue a grant from your backend
Add an authenticated route to your backend. Check that the signed-in user is allowed to act on the thread, then ask the Engine for a grant using a service account’s API key:
The key must belong to a service account. The Engine refuses to issue grants to
requests that come from a browser.
3. Connect from the page
getAccessToken again before the grant expires, so the
connection stays open. Browser connections must use https:// outside of
localhost.
From here, thread(), step(), waitFor() and the other thread methods work as
they do in Node.js, within what the grant allows.
Reading history
A grant doesn’t allow GraphQL reads or subscriptions. To show history in the page, add a backend endpoint that checks the user’s access and runs only the queries you approve, and pass it asgraphqlUrl. It must be on the same origin
as the page. Never expose an unrestricted proxy that uses your API key.
Capture clicks and form submissions
Instead of callingstep() for every button, you can let the SDK record user
actions on part of the page:
- Capture is off until you call
autoCapture, and only covers the elements inside the scopes you register. includelists the actions to record, as CSS selectors or as names from adata-threadify-actionattribute.- An action listed in
stepsrecords that contract step. Other actions are stored as activity on the thread but don’t complete any step. - You can also map an element in HTML with
data-threadify-step="order_placed".
What data is captured
Nothing from form fields is read unless you mark it:data-threadify-context-<name>attributes on the element or its parents add that value as context (order_idhere).- On a form submission, inputs marked with
data-threadify-context="<name>"add their values. - Password and file inputs are never read.
Record an action yourself
classification says what
happened: mapped_step (a step was recorded, with its stepId),
mapping_rejected (it was mapped to a step, but the step was refused, with a
message), or free_form, step_candidate or substep (kept as activity).
Map actions in the dashboard
Admins can also map actions to steps without changing the page. On a contract version’s page, open Input config and add oneaction=step rule per line,
for example click:place-order=order_placed. Several actions can share a step:
click_a,click_b=order_placed.
These rules apply to captured browser actions and to OpenTelemetry spans on
threads using that contract, from the time you save them. Earlier activity isn’t
changed. Steps reported directly with step() aren’t affected.