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.
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }
]
}
}
})
<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.
- 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
head property in nuxt.config.js using script: [{ src: 'https://floorsjs.com/embed.js', 'data-key': 'flr_...' }]. Works the same way.useHead call in a process.client check or use a v-if condition to only inject the script for certain users or environments.