How it works
floors.js runs completely outside Angular's zone. 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.
Angular Router uses pushState for navigation. When a visitor moves from /dashboard to /settings, floors.js picks that up automatically. No NgModule, no service injection, no change detection triggered. It doesn't interact with Angular's zone.js at all.
Because it operates at the browser level, it works with lazy-loaded routes, route guards, child routes, and parameterized routes — all out of the box.
Installation
Add the floors.js script tag to your src/index.html file, right before the closing </body> tag.
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<app-root></app-root>
<!-- floors.js — add before </body> -->
<script src="https://floorsjs.com/embed.js" data-key="flr_..."></script>
</body>
</html>
Replace flr_... with your site key from the floors.js dashboard. The script loads asynchronously and won't interfere with Angular's bootstrap process.
Works with Angular Router
Every route in your Angular app becomes a room in floors.js. Navigation is detected automatically regardless of how your routing is configured.
- Lazy-loaded routes —
loadChildrenandloadComponentwork seamlessly; floors.js detects the URL change, not the loading strategy - Route guards —
canActivate,canDeactivate,resolve— floors.js only tracks the final URL after guards pass - Child routes — nested
router-outletcomponents are fully supported; the full URL path determines the room - Parameterized routes —
/products/:id→ each product page is its own room
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
ngOnInit or afterNextRender if you want to load floors.js only for certain users or environments.
floors