JavaScript widget
The Patchrooms widget is a small browser script that docks a feedback room to the
edge of your app. It ships as a global Patchrooms object once loaded.
There are two ways to load it.
Loading the widget
Section titled “Loading the widget”Per-project loader (recommended)
Section titled “Per-project loader (recommended)”Drop one script tag into your page. The URL carries your project key, and the server returns a tiny loader with your widget configuration and channels baked in — the room renders themed immediately and initializes itself.
<script src="https://room.patchrooms.com/v1/patchrooms/pr_xxx.js"></script>Replace pr_xxx with your public project key from the dashboard. No
Patchrooms.init() call is needed — the loader auto-initializes.
Programmatic loader
Section titled “Programmatic loader”Load the shared bundle and call init() yourself. Use this when you need to
control timing (for example, a single-page app that re-parents the widget
between routes).
<script src="https://room.patchrooms.com/v1/patchrooms.js"></script><script>Patchrooms.init({ projectKey: 'pr_xxx' });</script>init(options)
Section titled “init(options)”Initializes the widget and mounts it. init() is idempotent — calling it again
tears the widget down and rebuilds it with the new options. projectKey is the
only required field (except in local storage mode).
Patchrooms.init({ projectKey: 'pr_xxx', locale: 'en', anchor: 'bottom-right',});InitOptions
Section titled “InitOptions”| Option | Type | Default | Description |
|---|---|---|---|
projectKey | string | — | Public project key from the dashboard. Required (except in local storage mode). |
locale | 'en' | 'ru' | auto-detect | Widget UI language. Falls back to navigator.language. |
apiUrl | string | script origin, else https://room.patchrooms.com | Ingest API base URL. |
userId | string | — | Optional user identifier, forwarded with every report. |
extra | Record<string, unknown> | — | Extra fields attached to context.extra on every submission. |
captureConsoleErrors | boolean | true | Hook console.error so the last 10 errors auto-attach to reports. |
mascot | MascotId | 'fox' | Mascot character. See mascots. |
shape | ShapeId | 'bubble' | Container shape glued to the viewport edge. See shapes. |
anchor | WidgetAnchor | 'middle-right' | Anchor corner/edge of the viewport. See anchors. |
triggerVariant | 'frame-tab' | 'devwidget' | 'frame-tab' | Trigger launcher style. |
size | number | 44 | Trigger size in px (square shell), clamped to 32–64. |
offsetX | number | 0 | Horizontal offset from the anchor in px (positive = inward). |
offsetY | number | 0 | Vertical offset from the anchor in px (positive = inward). |
widgetId | string | auto | Unique id for cross-widget collision avoidance. |
attributes | Record<string, unknown> | — | Initial host attributes, copied into custom.* at init time. |
onChannelChange | (next, prev) => void | — | Called whenever the active channel changes (including to null). Each argument is { key: string } | null. |
pushToTalkKey | string | — | KeyboardEvent.key for push-to-talk audio capture while the panel is open. Opt-in. |
mode | 'default' | 'artifact-review' | 'default' | Operating mode. artifact-review attaches artifact metadata to reports. |
artifact | ArtifactMeta | — | Artifact under review (used in artifact-review mode). |
storage | 'cloud' | 'local' | 'cloud' | Where reports are stored. local keeps everything in localStorage with no network calls. |
Mascot IDs
Section titled “Mascot IDs”gecko · owl · fox · cat · axolotl · raccoon · chameleon · otter · robot · blob
Shape IDs
Section titled “Shape IDs”frame-tab · bubble · tab · pill · blob
Anchors
Section titled “Anchors”top-left · top-center · top-right · middle-left · middle-right · bottom-left · bottom-center · bottom-right
Methods
Section titled “Methods”All methods below are properties of the global Patchrooms object. Except for
init() and destroy(), they throw if the widget has not been initialized.
report(options?)
Section titled “report(options?)”Files a one-shot report programmatically. The message becomes a single text
block in the active channel. Returns a Promise that rejects if the submission
fails.
await Patchrooms.report({ message: 'Checkout button is misaligned on mobile', extra: { route: '/checkout' },});| Option | Type | Description |
|---|---|---|
message | string | Report text. Becomes a single text block. |
extra | Record<string, unknown> | Merged into context.extra for this report. |
alpha(featureKey)
Section titled “alpha(featureKey)”Checks whether an alpha feature flag is enabled for the current user and, if so,
marks it on the widget. Returns a Promise<boolean>.
const enabled = await Patchrooms.alpha('new-dashboard');show()
Section titled “show()”Shows the widget.
hide()
Section titled “hide()”Hides the widget.
openForm()
Section titled “openForm()”Opens the report panel programmatically.
destroy()
Section titled “destroy()”Tears down the widget and clears SDK state. Safe to call when not initialized —
it becomes a no-op. After destroy() the SDK can be re-initialized with a
different projectKey or apiUrl.
setAttribute(key, value)
Section titled “setAttribute(key, value)”Sets a single attribute on the channel engine. Attributes feed channel matching.
Patchrooms.setAttribute('custom.plan', 'pro');setAttributes(obj)
Section titled “setAttributes(obj)”Sets multiple attributes at once.
Patchrooms.setAttributes({ 'custom.plan': 'pro', 'custom.role': 'admin' });setChannel(key, options?)
Section titled “setChannel(key, options?)”Forces the active channel. The optional weight (number | 'max' | 'suggest')
controls how strongly the override applies.
Patchrooms.setChannel('bug', { weight: 'max' });clearChannelOverride()
Section titled “clearChannelOverride()”Clears a manual channel override and lets automatic matching resume.
getActiveChannel()
Section titled “getActiveChannel()”Returns the currently active channel (or null).
getChannels()
Section titled “getChannels()”Returns the list of channels currently known to the widget.