Integration Guide
Add floors.js to Nuxt
Add one line to your nuxt.config. floors.js detects route changes from Vue Router automatically — no Nuxt plugin, no composable, no npm package.
How it works
floors.js runs completely outside Nuxt and Vue. 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.
Under the hood, Nuxt uses Vue Router for all navigation. When a visitor moves from /pricing to /docs/getting-started, Vue Router calls pushState, and floors.js picks that up automatically. No Nuxt plugin, no Vue composable, no re-renders.
Because it works at the browser level, it's compatible with Nuxt 3, Nuxt 2, file-based routing, dynamic routes, and middleware — all out of the box.
Installation
There are two ways to add floors.js to a Nuxt app. Both work identically.
Option 1 — nuxt.config.ts (recommended):
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }
]
}
}
})
Option 2 — useHead in app.vue or layouts/default.vue:
<!-- app.vue or layouts/default.vue -->
<script setup>
useHead({
script: [{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }]
})
</script>
Replace flr_... with your site key from the floors.js dashboard. The script loads asynchronously and won't block your app's rendering or hydration.
Works with Nuxt routing
Nuxt's file-based routing maps directly to floors.js rooms. Every route in your pages/ directory becomes a room that visitors can inhabit together.
- Static routes —
pages/about.vue→ visitors on/aboutare in the same room - Dynamic routes —
pages/blog/[slug].vue→ each blog post is its own room - Nested routes —
pages/dashboard/settings.vue→/dashboard/settingsis a separate room - Catch-all routes —
pages/[...slug].vue→ each resolved path gets its own room
No configuration needed. Middleware, layouts, and route guards don't affect floors.js — it only cares about the final URL in the browser.
Configuration
All settings are managed from your floors.js dashboard. Changes apply instantly, no code update needed. You can also use attributes in nuxt.config as an optional fallback.
{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }
- 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
See the full list of data-attributes in the docs.
FAQ
Do I need a Nuxt plugin?
No. floors.js is a standalone script that runs entirely outside Nuxt's plugin system. There's no module, no composable, no build-time integration. Just a script tag.
Does it work with Nuxt 2?
Yes. In Nuxt 2, add the script to the head property in nuxt.config.js using script: [{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }]. Works the same way.
What about SSR?
floors.js only runs client-side. During server-side rendering, the script tag is included in the HTML but doesn't execute until the browser loads it. No SSR errors, no hydration mismatches.
Works with Nuxt Content?
Yes. Each Nuxt Content page (Markdown, MDC, or YAML) gets its own URL, which becomes its own room in floors.js. Readers on the same docs page see each other automatically.
Can I load it conditionally?
Yes. Wrap the useHead call in a process.client check or use a v-if condition to only inject the script for certain users or environments.
Alternatives & Comparisons
- Intercom Alternative
- Crisp Alternative
- Tidio Alternative
- tawk.to Alternative
- vs Gather
- vs SpatialChat
Welcome to floors.js - Live Demo
Enter the building to see and chat with other visitors in real-time.