Use RightMessage in a single-page application
Install RightMessage once, let it observe client-side routes, and preserve visitor context through supported managed redirects.
Updated
View as MarkdownInstall RightMessage once in your application's shared page shell. The runtime observes client-side URL changes automatically, so React, Vue, Svelte, Angular, Next.js, and Nuxt do not need a second RightMessage router hook.
You need access to the application's source and the project's production installation snippet. Publish the flows, widgets, and campaigns you want normal visitors to use. Installing the snippet does not publish draft configuration.
Install the complete snippet once
- Copy the project's generated production installation snippet.
- Add it to the shared document head or your framework's persistent document layout.
- Keep the complete generated snippet, including its startup configuration and cloak cleanup. Do not replace it with a guessed script URL.
- Remove duplicate installations from route components, page-level effects, or a second tag-manager rule.
For a client-rendered application, use the HTML shell. For a server-rendered framework, use its supported global script mechanism.
Do not execute browser-only code during server rendering. Keep the snippet mounted across client-side navigation rather than removing and reinstalling it for every route.
The development snippet's useDraftConfig setting starts an authenticated draft-debugger session. It is not an anonymous staging mode or an analytics-off switch. Without a valid debugger token, RightMessage requests authorization, which can require signing in. Use an authorized debugger session to inspect a draft. The runtime falls back to published configuration when the draft request fails.
Remove redundant route resets
If your application already calls RM.push(['reset']) from every router transition, remove that hook and retain the installation snippet.
RightMessage observes history.pushState, history.replaceState, browser back and forward through popstate, and hash changes. It also observes the Navigation API's navigatesuccess and currententrychange events when available. It updates route-dependent visual state and query context, then records a pageview after a 100-millisecond debounce.
RightMessage uses the full URL to decide whether to record a pageview. Repeated notifications for the same URL do not create another pageview. When URLs change rapidly, only the final route may produce a pageview.
Avoid replacing the History methods after RightMessage has installed its observers. If another library wraps them, preserve the existing implementation instead of discarding it.
Reset only for state changes without a new URL
If your application changes state that RightMessage reads without changing the URL, request a reset after that state is available.
Illustrative call, not executed:
The reset refreshes derived sources, widgets, and campaigns. It does not itself identify a logged-in user, publish a draft, or fetch every provider field. For a known email-platform contact, use the appropriate identification command in Browser JavaScript commands and events.
Use personalize when you only need campaign reconciliation. Neither command is a replacement for your application's own rendering lifecycle.
Use current or remembered query values deliberately
For a condition or template that should apply only to the current route, use query.current.<name>. To retain the most recent occurrence of a parameter as the visitor navigates, use query.<name>.
For example, a WorkForge visitor can arrive at https://example.com/?utm_campaign=teams and then navigate to /pricing. On /pricing, query.current.utm_campaign is absent, while query.utm_campaign can still be teams from stored page history. Empty strings and '0' count as present values.
See Flow data and Liquid reference for context paths and types.
Carry context through RightMessage-managed redirects
To preserve context when a flow sends a visitor to another configured site or subdomain, use the flow's redirect or the offer's redirect handling. Install the appropriate RightMessage project snippet at the destination too.
For a synthetic WorkForge setup, the journey might start at https://www.example.com/quiz and finish at https://app.example.com/recommendation. RightMessage-managed redirect handling can add _rm to the destination URL. Do not build a separate encoder or manually copy a visitor's context into a reusable public link.
The carried context contains visitor and provider identifiers, recorded answers, identity scope, and a bounded set of campaign assignments. It is not a complete browser-storage export. The destination validates carried answer IDs against its configuration and reevaluates signal-based segmentation. Identical-looking segment names across different projects are not sufficient.
This mechanism does not rewrite every ordinary link on your website. A normal anchor, your own window.location assignment, or an unrelated router link is not automatically a managed redirect. Browser cookies also cannot span unrelated registrable domains.
At the destination, valid URL context takes precedence over _rm_ctx cookie fallback. After consuming URL context, RightMessage removes _rm with History rather than reloading the page. Query stripping by your own router or redirect service before the tag reads the URL can prevent this transfer.
Account for cookie and payload limits
The _rm_ctx cookie normally lasts 365 days and targets an estimated registrable domain for subdomain continuity. It uses SameSite=Lax, / as its path, and Secure on HTTPS. Blacklisted hosts, including localhost by default, do not use this cookie. If the browser rejects the shared domain, the runtime falls back to a host-only cookie, which cannot provide cross-subdomain continuity.
The transport has a 3,500-character encoded budget. Campaign assignments use remaining capacity, with at most 1,200 additional encoded characters and 128 entries. A large base identity or answer payload is not guaranteed to fit a browser's cookie limit. The budget does not guarantee lossless transport of all data.
Provider identity scope restricts which configured project and connection can reuse an identifier. It is not encryption, a signature, or proof of identity. _rm and _rm_ctx are client-carried, decodable values. Never use them to authorize protected content, log someone into your application, or bypass server-side access checks.
Debugger and preview context do not establish normal visitor continuity. Do not use a debugger impersonation as proof that a production cross-domain journey has identified the visitor.
Confirm the route behavior
After installation, inspect your own site with a test visitor:
- Open a direct route and navigate to another route without reloading.
- Use browser back and forward.
- Check that widgets and personalization follow the destination's URL rules.
- Compare a query-bearing route with a later route that omits that parameter.
- If your flow uses a managed redirect, follow that actual flow and inspect the destination's visitor context.
If the wrong content remains, check the loaded snippet, the published page rules, the visitor's current segments, and browser console errors. Separate a route-detection problem from a campaign selector that no longer matches the framework's rendered HTML.
For synthetic visitor data, use a valid __rm_test payload. An invalid payload does not disable tracking, and analytics suppression is not a guarantee that custom JavaScript or provider writes are blocked.