Skip to help content
RightMessage
DevelopersReference

Browser JavaScript commands and events

Look up browser RM commands, identification callbacks, widget controls, data clearing, and rm CustomEvent payloads.

Updated

View as Markdown

Use the browser API to identify a visitor, control widgets, or respond to RightMessage activity on the current page. Commands use tuples passed to window.RM.push. Events use document.addEventListener. Neither interface is the local RM object available inside a flow Code node.

The API requires the RightMessage installation snippet. These commands act on the current visitor. They do not create or publish project configuration. Publish changes to flows, widgets, or segments before normal visitors use them. Commands that identify a visitor or alter answers can affect personalization and connected-provider activity immediately.

Queue and return contract

Illustrative queue setup, not executed:

JavaScript
window.RM = window.RM || [];
window.RM.push(['trigger', 'wdg_workforge_demo']);

Before initialization, RM is an array. push() returns its new length, not a Promise or a command result. When RightMessage initializes, it processes queued tuples and replaces push with a command dispatcher. Calls then execute immediately. Multiple tuples execute in order, and push returns the last command's return value.

There is no Promise that represents a previously queued call. lookup and identifyByEmail support callbacks for results across this boundary. A callback is a success-path callback, not an error-first callback. Use a returned Promise only when your code already knows that the dispatcher is initialized.

Unknown command names have no defined error behavior, and there is no general argument validation. Pass the exact command spelling and IDs from the current project.

Identification commands

TupleArgumentsReturn after initialization
['lookup', email, callback?]Email string; optional function receiving the lookup resultProvider lookup Promise. It looks up a contact ID without adopting that identity.
['identify', contactId]Nonempty provider contact IDPromise resolving after the profile read and derived refresh. It does not return the fetched profile.
['identifyByEmail', email, callback?]Email string; optional function receiving contact ID or nullPromise resolving to the adopted contact ID, or null when none is adopted.
['prepopulate']No argumentsPromise resolving after a forced integration-profile refresh and derived refresh. It does not return the fetched profile.

lookup

Without an integration, the command warns and rejects with 'No integration configured'. With an integration but no email, it returns undefined. Other lookup failures follow the provider Promise. The optional callback runs only when that Promise resolves.

A lookup is not contact creation, opt-in, or identification. Its miss result depends on the provider lookup. Use identifyByEmail when the goal is to adopt an existing contact.

identify

A nonempty ID becomes the current subscriber identifier before a forced profile read. With no ID argument, the runtime refreshes the current identity rather than clearing it. Without an integration, it warns and returns undefined.

The returned Promise settles through the refresh path even when the profile read fails. Resolution is not proof that a valid profile was found. Provider identification events can describe anonymous or failed states too.

identifyByEmail

Missing email rejects with 'Email address required'. Missing integration rejects with 'No integration configured'. Lookup errors warn and become null. A lookup miss does not replace the existing identity. A newer lookup supersedes an older one, so an old response cannot restore a previous visitor identity.

The command waits for the adopted identity's profile fetch attempt. A contact ID result does not guarantee that every profile field loaded successfully. A callback exception can reject the returned Promise.

Illustrative queued call, not executed:

JavaScript
window.RM = window.RM || [];
window.RM.push([
	'identifyByEmail',
	'visitor@example.com',
	(contactId) => {
		console.log(contactId === null ? 'No contact adopted' : 'Contact adopted');
	}
]);

An illustrative callback value is 'contact_workforge_42' when lookup and identity adoption succeed, or null when they do not. Identification is not authentication. Never use this result to grant account access.

prepopulate

This forces a refresh of the connected profile and joins compatible in-flight work. Without an integration, it logs a message and returns undefined. As with identify, Promise resolution is not a provider-success receipt.

Widget and rendering commands

TupleEffectReturn
['trigger', widgetId]Requests that the specified widget show. The widget must exist in the loaded configuration.undefined
['hide', widgetId]Requests that the specified widget hide.undefined
['personalize']Reconciles current campaign output. Dependencies that are still loading can remain pending. Campaign personalization requires Scale or Pro.undefined
['reset']Accepts a pending URL change if necessary, refreshes derived sources, and reruns widgets and campaigns.undefined

Widget IDs are strings such as wdg_workforge_demo. Triggering does not return proof of visibility. personalize does not republish configuration, reroll unchanged holdbacks, or repeat an unchanged campaign exposure.

Normal SPA routes are observed automatically. A second route hook that calls reset is unnecessary. See Use RightMessage in a single-page application.

Answers and browser data

TupleEffectReturn
['addSegment', segmentId]Records the exact segment ID as an answer and emits a segmentation refresh. This tuple does not perform name lookup or explicitly clear sibling answers.undefined
['removeSegment', segmentId]Removes that recorded answer and emits a segmentation refresh.undefined
['clearAnswers']Clears recorded segment answers, input values, input parts, and question-sync metadata, then refreshes segmentation.undefined
['clearAllData']Purges RightMessage browser storage and context cookies, clears identities, answers, profile state, and test or holdback assignments, and refreshes visitor state.Purge result object below

A removed answer can still match a segment through its signal rules or connected profile. These commands do not delete segment definitions. Unlike Code-node segment methods, the browser tuples emit refresh events for external callers.

clearAllData preserves debugger preferences. It does not delete the email-platform contact, undo completed provider writes, or delete historical server-side analytics. Storage removal is best effort.

Illustrative result shape, not executed:

JSON
{
	"localStorageKeys": ["rm_variables", "rmpanda.rightask.answers"],
	"sessionStorageKeys": ["rm_dismissed_widgets"],
	"removedVisitorContextCookie": true
}

The arrays list matching keys selected for removal. The cookie boolean indicates that the host was eligible for the context-cookie removal attempt. Neither is proof that the browser accepted every removal.

DOM CustomEvents

Listeners belong on document. Payloads are in event.detail. These events report runtime activity, not a transactional provider receipt or a promise of delivery to your listener. Register listeners before the activity you need to observe.

EventDetail shape and meaning
rm:syncDetails{ fields, tags }. Field entries include partnerName, fieldId, and fieldValue; tags is { add: [tagId], remove: [tagId] }. Describes the synchronization pass, which can include queued or skipped fields.
rm:identify{ esp, data }. esp is the integration's runtime name; data is its visitor context, which can be anonymous.
rm:segmentation{ segmentGroups: { [dimensionId]: { [segmentId]: boolean } } }. Nested group decisions, not a flat array of active segments.
rm:forced-segment-id{ segmentId }. A forced segment ID was read from the runtime's forced-segment context. It can repeat during recalculation.
rm:sources:page-view:save-page-viewNo application detail payload. The runtime is saving a pageview. This is not an analytics-ingestion acknowledgement.
rm:widget:acceptOffer{ widgetId, widgetName, offerId, offerName, formData }. formData is the submitted data or null. Acceptance does not prove a subsequent provider write succeeded.
rm:widget:inputAnswer{ widgetId, widgetName, questionId, inputType, inputValue }. An input question answer.
rm:widget:answer{ widgetId, widgetName, dimensionId, dimensionName, segmentId, segmentName }. A segment-choice answer.
rm:widget:dismissed{ widgetId, widgetName, widgetType, flowId }. flowId can be null.
rm:widgetUpdated{ widgetId, widgetName, currentStep, width, height, top, left }. Current step and measured widget geometry. The four geometry values are 0 when the widget element cannot be found.

The first five events have bubbles: true and cancelable: true. The widget events above are dispatched directly on document with the default non-bubbling, non-cancelable flags. No listed event provides a supported preventDefault() veto over conversions, navigation, or provider writes.

In debugger sessions, RightMessage can record these events as proposed writes rather than dispatching them to your listeners.

Illustrative listener and event detail, not executed:

JavaScript
document.addEventListener('rm:widget:answer', (event) => {
	const { dimensionId, segmentId } = event.detail;
	console.log({ dimensionId, segmentId });
});
JSON
{
	"widgetId": "wdg_workforge_quiz",
	"widgetName": "WorkForge quiz",
	"dimensionId": "dim_workforge_role",
	"dimensionName": "Role",
	"segmentId": "seg_workforge_manager",
	"segmentName": "Manager"
}

Avoid forwarding entire event payloads to third-party analytics. Identification and form events can contain email addresses and other personal data.

Exclude a form from automatic observation

The presence of data-rm-form-ignore on a form opts it out of RightMessage's automatic form observer. The value is not interpreted as a boolean, so data-rm-form-ignore="false" still opts out.

The form observer is created for a Popup widget using After a form is submitted. Installing the snippet alone does not enable this observer for every site form. The opt-out applies to that observer, not every identification path. See Identify visitors automatically for Email Watcher and other supported methods.

Illustrative markup, not executed:

HTML
<form action="https://example.com/search" data-rm-form-ignore>
	<input name="query" type="search">
	<button type="submit">Search WorkForge</button>
</form>

This exclusion does not prevent your own JavaScript from calling identification commands. Runtime-owned attributes such as data-rm-form-id and data-rm-question-input are not substitutes for the opt-out attribute.

Still need a hand?

Tell us what you’re trying to do and where you’re getting stuck.

support@rightmessage.com