How it works
floors.js runs completely outside React and Gatsby. It patches the browser's history APIs to detect @reach/router navigation — the router Gatsby uses under the hood.
When a visitor clicks a Gatsby <Link> from /about to /blog/hello-world, @reach/router calls pushState, and floors.js picks that up automatically. No Gatsby plugin, no GraphQL, no build-time integration.
Installation
The recommended approach is to use gatsby-ssr.js to inject the script into every page at build time.
import React from "react"
export const onRenderBody = ({'{ setPostBodyComponents }'}) => {
setPostBodyComponents([
<script
key="floors"
src="https://floorsjs.com/embed.js"
data-key="flr_..."
/>
])
}
Replace flr_... with your site key. The script loads asynchronously and won't affect Gatsby's build performance or hydration.
Works with Gatsby routing
Every page in your Gatsby site becomes a room in floors.js — whether it's a file-based page, programmatically generated, or a client-only route.
- File-based pages — pages in
src/pages/each become a room automatically - Programmatic pages — pages created via
createPagesin gatsby-node.js work the same way - Client-only routes — dynamic routes using
matchPathare detected when the URL changes - MDX pages — each MDX page gets its own room for readers to chat
Configuration
All settings are managed from your floors.js dashboard. Changes apply instantly, no code update needed. You can also use data- attributes 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
gatsby-browser.js and the onClientEntry API to inject the script only in certain conditions — for example, only in production.