@marketrix.ai/widget
v5.1.37
Published
Readme
Marketrix Widget
The embeddable Marketrix support widget. Drop it into any web page and your users get an in-product assistant that can Tell them how something works, Show them step-by-step with on-page highlighting, or Do the task for them in the browser.
Published to npm as @marketrix.ai/widget. Ships as a single ES module (widget.mjs) plus a classic loader.js bootstrap.
React 19 is required. The widget treats
reactandreact-domas peer dependencies and does not bundle them — the host page must provide React 19. The script-tag loader injects a React 19 importmap for you; npm consumers already have React in their app.
Install
There are two integration paths. Most sites should use the script tag — it's the simplest and provides React for you.
1. Script tag (recommended)
Add one <script> to your page <head>, before any <script type="module"> tags (the loader installs the React importmap that your module scripts rely on):
<script
src="https://widget.marketrix.ai/loader.js"
mtx-id="your-marketrix-id"
mtx-key="your-marketrix-key"
mtx-api-host="https://api.marketrix.ai"
></script>loader.js:
- Injects a React 19 importmap pointing at
esm.sh/react@19, unless an import map already on your page mapsreact,react-dom,react-dom/clientandreact/jsx-runtime. If your page has an import map that lacks those entries, add them to it: Firefox, Chrome before 133 and Safari before 18.4 ignore every import map after the first, so the loader's map would not load React there. Where several maps are supported, an earlier map's keys win, so a host that already ships React 19 keeps its own copy. - Injects
<script type="module" src=".../widget.mjs">from the same origin as the loader. - Forwards every
mtx-*attribute from the loader tag to the widget.
The widget then auto-initializes from those attributes — no extra JavaScript required.
2. npm / programmatic
npm install @marketrix.ai/widget
# react@^19.2.3 and react-dom@^19.2.3 must already be installed in your appimport { mountWidget } from '@marketrix.ai/widget';
await mountWidget({
mtxId: 'your-marketrix-id',
mtxKey: 'your-marketrix-key',
mtxApiHost: 'https://api.marketrix.ai',
});mountWidget auto-detects the credential mode (production / preview) from the config you pass.
Credential modes
The widget supports two modes, auto-detected from the credentials you provide.
| Mode | Credentials | Script attributes | Network |
| -------------- | --------------------------------- | ------------------------------------- | --------------------------------------------------------------- |
| Production | mtxId + mtxKey + mtxApiHost | mtx-id + mtx-key + mtx-api-host | Fetches settings from the API, opens the live stream |
| Preview | settings object passed in code | — | No network — renders appearance only from the supplied settings |
All modes also accept the common options below.
Configuration options
These apply to every mode (script attribute → config key):
| Config key | Script attribute | Type | Description |
| ------------------------- | --------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| container | — | HTMLElement | Element to mount inside (programmatic only). Defaults to a container appended to <body>. |
| widget_position_z_index | — | number | z-index floor for the launcher and panel. Raised to the widget's own layer token if you pass a lower value. |
| show_widget | — | boolean | When false, the widget initializes fully but its UI stays hidden. Default true. |
| use_screenshare | mtx-use-screenshare | boolean | When false, the widget never asks to share the screen (Show and Do still work on the page) and the Share Screen button is hidden. Default true. Disable via mtx-use-screenshare="false". |
| styleNonce | mtx-style-nonce | string | A CSP nonce applied to the widget's injected <style> element. Required only if your style-src policy has no 'unsafe-inline' — see Content Security Policy. |
Widget appearance and behavior (position, colors, sizing, enabled Tell/Show/Do features, visibility, greeting toast, optional session recording, header/body/greeting text, and quick-action chips) are configured in the Marketrix dashboard and fetched from the API at init; border radius and animation timing are fixed defaults. A hidden widget stays visible in the dashboard preview.
Full script-tag example
<!doctype html>
<html>
<head>
<script
src="https://widget.marketrix.ai/loader.js"
mtx-id="your-marketrix-id"
mtx-key="your-marketrix-key"
mtx-api-host="https://api.marketrix.ai"
mtx-use-screenshare="false"
></script>
</head>
<body>
<!-- your app -->
</body>
</html>The loader takes care of the React 19 importmap. If you manage your own importmap, place it before the loader; your entries win and the loader's map only fills what is missing:
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@19",
"react-dom": "https://esm.sh/react-dom@19",
"react-dom/client": "https://esm.sh/react-dom@19/client",
"react/jsx-runtime": "https://esm.sh/react@19/jsx-runtime"
}
}
</script>
<script src="https://widget.marketrix.ai/loader.js" mtx-id="..." mtx-key="..." mtx-api-host="..."></script>Programmatic API
All functions are named exports of @marketrix.ai/widget.
import {
mountWidget,
initWidget,
unmountWidget,
updateMarketrixConfig,
getCurrentConfig,
MarketrixWidgetPreview,
} from '@marketrix.ai/widget';mountWidget(config): Promise<void>
Auto-detects the mode (preview / production) from config and initializes the widget, rejecting if neither settings nor mtxId + mtxKey + mtxApiHost is present, if preview settings are invalid, or if production init fails. The recommended entry point for programmatic use.
// Production
await mountWidget({ mtxId, mtxKey, mtxApiHost });
// Preview (no network — just renders the appearance)
await mountWidget({ settings: { widget_enabled: true, widget_position: 'bottom_right' /* ... */ } });initWidget(config, container?): Promise<void>
Lower-level production initializer. Validates credentials, fetches settings from the API, mounts into a closed Shadow DOM, and opens the event stream. Optionally mounts inside a specific container. Concurrent and duplicate calls are deduplicated; only one production widget runs per page. It rejects when the widget cannot load (a missing API host, rejected credentials, invalid settings), after showing the visitor a notice.
await initWidget({ mtxId, mtxKey, mtxApiHost }, document.getElementById('my-container')!);unmountWidget(): void
Destroys the widget, closes the stream connection, and cleans up all resources.
updateMarketrixConfig(partial): Promise<void>
Merges partial (a Partial<MarketrixConfig>) into the current config and re-mounts: a preview stays a preview, a live widget re-runs initWidget. Use to switch API host, credentials, etc. at runtime.
getCurrentConfig()
Returns the active configuration — your options merged with the dashboard settings — or null if the widget isn't initialized.
Settings
Widget settings are managed in the dashboard. widget_appearance: 'hidden' keeps the widget initialized but suppresses its visible UI on the host page; previews remain visible. widget_greeting_toast controls the welcome toast, and widget_recording enables Session recording. Recording is off by default.
Session recording privacy
When recording is enabled, every input value is masked — recordings capture that a field was typed into, never what was typed. To exclude more of your page, add either class to any element:
| Class | Effect |
| ------------------------ | ----------------------------------------------------------- |
| mtx-mask / rr-mask | Text content inside the element is masked |
| mtx-block / rr-block | The element is replaced by a placeholder and never recorded |
Both the mtx- and rrweb's native rr- prefixes are honoured, so existing rr-block / rr-mask markup keeps working.
MarketrixWidgetPreview — React component
For previewing appearance inside a React app (e.g. a settings/configuration screen). Renders into its own Shadow DOM and makes no network calls.
import { MarketrixWidgetPreview } from '@marketrix.ai/widget';
function Preview() {
return (
<MarketrixWidgetPreview
settings={{ widget_enabled: true, widget_position: 'bottom_right' /* ...WidgetSettingsData */ }}
/>
);
}Props: settings (required) and container?. Invalid settings throw during render, naming the invalid fields, so wrap the preview in your error boundary.
Interaction modes
- Tell — the agent explains concepts and answers questions in chat.
- Show — the agent walks the user through a task step-by-step, highlighting the relevant elements on the page.
- Do — the agent performs the actions in the browser on the user's behalf.
A Show or Do task keeps running across same-origin page navigations in the same tab. A mode switched off in the dashboard is never sent: its chips are hidden and the composer uses the first enabled mode.
Exported types
TypeScript types are bundled with the package:
MarketrixConfig— whatinitWidgettakes: the requiredmtxId+mtxKey+mtxApiHost(the API server URL, e.g.https://api.marketrix.ai; there is no baked-in default) plusClientOwnedConfig. Appearance comes only from the dashboard settings;updateMarketrixConfigtakes aPartial<MarketrixConfig>.AddWidgetConfig— discriminated config formountWidget(production / preview variants + common options).ClientOwnedConfig— the host-supplied options the API never sends (widget_position_z_index,show_widget,use_screenshare,styleNonce).MarketrixWidgetPreviewProps— props for theMarketrixWidgetPreviewcomponent.WidgetSettingsData— the dashboard settings shapeMarketrixWidgetPreviewand preview-modemountWidgettake.InstructionType('tell' | 'show' | 'do').
Upgrading to 5.1
initWidgetandmountWidgetnow reject when the widget cannot load, where they used to resolve after showing the visitor a notice. Add a.catchif you awaited them without one.MarketrixWidgetPreviewand preview-modemountWidgetnow throw on invalidsettings, where they used to log to the console and render nothing.- Browsers below the floor in Requirements are no longer supported. The bundle used to target the newest syntax, with no declared floor.
Upgrading to 5.0.1
- TypeScript now requires
mtxApiHostinMarketrixConfigand in the credentials form ofAddWidgetConfig. The runtime already refused to start without it, so only type-checking changes; it is no longer part ofClientOwnedConfig. - Saved widget positions and panel sizes reset once. They are stored in a new format, so a visitor's dragged position and resized panel return to your dashboard defaults the first time 5.0.1 loads.
Upgrading to 5.0
5.0 narrows the public API. Each removal and what to use instead:
- Dashboard settings are no longer accepted in
MarketrixConfig. Thewidget_*appearance and behaviour keys (widget_accent_color,widget_background_color,widget_text_color,widget_position,widget_greeting,widget_chipsand the rest) were always overwritten by the dashboard settings. Set them in the dashboard; to render them before saving, pass them toMarketrixWidgetPreviewor preview-modemountWidgetasWidgetSettingsData.widget_position_z_indexstays, as aClientOwnedConfigoption. mtxAppandisPreviewModeare no longer config keys, andmtxId/mtxKeyare now required. The application resolves from your credentials; for a preview, useMarketrixWidgetPreviewor preview-modemountWidget.userIdis no longer a config key. The widget never sends a user id; drop it from your config. A 4.x widget still configured withuserIdno longer connects, because the api refuses theuser_idit sends; 4.x widgets withoutuserIdare unaffected.- The default export is gone. Import the named exports instead:
import { initWidget } from '@marketrix.ai/widget'. - The
WidgetStateandChatMessagetypes are no longer exported. Nothing in the public API produced or accepted them, so delete those imports. - With no suggested actions configured, a live widget shows none. Previously a live widget showed built-in example chips. Those examples now appear only in preview.
Requirements
- A browser at or above Safari 16.4, Chrome/Edge 111 or Firefox 111 — the bundle's build target. Safari 16.4 is the first Safari with import maps, which the script-tag loader relies on.
- React 19 (
react/react-dom^19.2.3) on the host page — peer dependency, not bundled. The script-tag loader provides it via importmap; npm consumers supply it from their app. - A reachable Marketrix API host (
mtxApiHost/mtx-api-host). - Valid credentials (
mtxId+mtxKey) for production mode.
Content Security Policy
The widget mounts into a closed Shadow DOM and injects its own stylesheet as an inline <style>
element inside it (there is no external stylesheet to point a <link> at). A host page enforcing a
style-src policy with no 'unsafe-inline' blocks that element, leaving the widget mounted but
entirely unstyled. If your policy is that strict, either:
- add
'unsafe-inline'tostyle-src(simplest, and scoped to styles only), or - generate a per-request nonce, add it to your
style-srcpolicy (style-src 'nonce-<value>'), and pass the same value asstyleNonce(programmatic) ormtx-style-nonce(script tag) — the widget applies it to its injected<style>element.
The widget makes network requests only to the configured mtxApiHost, with credentials explicitly
omitted on every request (it authenticates via mtxId/mtxKey, never a cookie), so connect-src needs
only that host. The script-tag loader also imports React from https://esm.sh unless your page's import
map already provides it, so a script-src policy must allow that origin or supply React itself; an npm
install contacts no third-party origin.
License
Apache License 2.0 — see the LICENSE file.
Support
Contact the Marketrix team or open an issue in the repository.
