How to add a live chat widget to a React or Next.js app

By The Roper team · Published · 4 min read

The short answer

To add a live chat widget to a React or Next.js app, load the widget's script once in your root layout (with next/script in Next.js, or an effect in a plain React app), pass the logged-in user before it loads or call identify after login, and open it from your own button with the widget's JavaScript API. Because the widget runs in its own iframe, route changes do not reload it.

1. Load the script once

Put the script in the root of your app so it loads on every page and only once. The widget needs your public workspace key as data-key; it is not a secret.

  • Next.js (App Router): in the root layout, render <Script src="https://your-roper-host/widget.js" data-key="wk_XXXX" strategy="afterInteractive" /> from next/script. Check your installed Next.js version's docs for the current Script options.
  • Plain React: in your top-level component, add the script element once in an effect and remove it on cleanup, or add the tag to index.html before </body>.
  • Any site: paste the snippet from Settings → Install before the closing body tag.

2. Pass the logged-in user

If you know who the user is, define window.RoperSettings before the widget script runs, with userId, name, email and any meta such as plan and company. They then appear in your inbox sidebar and you never ask "what's your email?".

In a single-page app the user often logs in after the script has loaded. In that case call window.Roper("identify", { userId, name, email, meta }) once the user is known. Identity set this way is not verified: anyone can set any userId, so do not use it to authorize anything.

3. Open it from your own button

Call window.Roper("open") from a Help link in your menu, and window.Roper("close") to close it. Guard the call: the script may still be loading, so check that window.Roper exists first.

4. Things that trip people up

  • Content Security Policy. If your app sets a CSP, allow your Roper host in script-src and frame-src.
  • Loaded twice. In development, React strict mode runs effects twice. Load the script from the layout, or guard against adding it again.
  • Server rendering. The widget is browser-only. Do not reference window during server render; use an effect or an event handler.
  • Logout. If a different user can log in on the same browser, call identify with the new user, and consider the privacy implications of shared devices.
  • Ad blockers. Some block chat widgets. Offer an email address as a fallback.

5. Check it works

  1. Reload the app and look for the launcher in the bottom-right corner.
  2. Send a message as a test customer and confirm it appears in your inbox with the user's details.
  3. Reply from the inbox and confirm the reply appears live in the widget.
  4. Open it from your Help link.

More on what the widget does is on the live chat widget page, and you can try it on the live demo.

Questions

Common questions

How do I add a chat widget to a Next.js app?
Add the widget's script to your root layout using next/script with afterInteractive, pass the user through window.RoperSettings or call identify after login, and open it with window.Roper("open") from your own button.
Will the widget reload on every route change?
No. It loads once and runs in its own iframe, so client-side navigation does not reload it, provided you load the script from the layout and not from a page.
Can I hide the launcher and use my own button?
Roper's widget shows its own launcher. You can add your own Help link that calls window.Roper("open"), but hiding the launcher is not a documented option.
Does the widget work with server components?
The script and its calls run in the browser. Place the script in a layout and put any calls to window.Roper in client components or event handlers.

Sources and how we wrote this

Roper is made by the team that wrote this post. Figures for other tools come from their own public pages, listed under Sources, and are list prices in US dollars that can change. If something here is out of date, tell us on the feedback board and we'll correct it.

Next steps