How it works
floors.js runs completely outside React. It loads as a standalone script that patches the browser's history APIs — pushState, replaceState, and the popstate event — to detect route changes in your app.
When a visitor navigates from /dashboard to /settings, floors.js picks that up automatically and moves them to the new room. No React context, no provider component, no re-renders. It doesn't touch your component tree at all.
Because it operates at the browser level, it works with every React router — BrowserRouter, HashRouter, MemoryRouter — and every meta-framework built on React.
Installation
Add the floors.js script tag to your HTML file, right before the closing </body> tag. That's it.
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<!-- floors.js — add before </body> -->
<script src="https://floorsjs.com/embed.js" data-key="flr_..."></script>
</body>
</html>
<script src="https://floorsjs.com/embed.js" data-key="flr_..."></script>
</body>
Replace flr_... with your site key from the floors.js dashboard. The script loads asynchronously and won't block your app's rendering.
Works with React Router
Whether you use BrowserRouter, HashRouter, or MemoryRouter, floors.js picks up URL changes automatically. Every route in your app becomes a room in the floors.js widget.
- BrowserRouter — floors.js patches
pushStateandreplaceState, so every<Link to="...">navigation is detected - HashRouter — hash changes trigger
popstate, which floors.js listens for - MemoryRouter — if routes reflect in the URL bar, floors.js will track them
No configuration needed. A visitor on /pricing and a visitor on /docs/api are in different rooms. They see each other when they're on the same route.
Configuration
All configuration is done via data- attributes on the script tag. No JavaScript API needed.
src="https://floorsjs.com/embed.js"
data-key="flr_..."
data-server="wss://your-server.com"
data-name="Jane"
></script>
- data-key (required) — your site key, used to group visitors across your domain
- data-server (optional) — custom WebSocket server URL if you're self-hosting
- data-name (optional) — pre-set the visitor's display name instead of generating a random one
FAQ
index.html in your project root (the one Vite uses as the entry point). It works in both development and production builds.public/index.html. CRA copies this file to the build output, so it'll work in both dev and production.
floors