# Integration Guide

## Add floors.js to _Angular_

Add one script tag to your index.html. floors.js detects Angular Router navigation automatically — no Angular module, no service, no npm package.

## 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
<!DOCTYPE html>
<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** — `loadChildren` and `loadComponent` work 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-outlet` components 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 settings — theme, accent color, rooms, pinned messages, and more — are managed from your [floors.js dashboard](/content/dashboard/index.html). Changes apply instantly to all visitors, no code update needed.

You can also use `data-` attributes on the script tag as an optional fallback. Dashboard settings always take priority.

```html
<script src="https://floorsjs.com/embed.js" data-key="flr_..."></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

See the [full list of data-attributes](/#docs) in the docs.

## FAQ

### Do I need an Angular module or service?
No. floors.js is a standalone script that runs entirely outside Angular. There's no NgModule, no injectable service, no decorator. Just a script tag in your index.html.

### Does it interfere with zone.js?
No. floors.js creates its own DOM elements and manages its own WebSocket connection. It runs completely outside Angular's zone, so it never triggers change detection or affects your app's performance.

### What about Angular Universal (SSR)?
The script 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.

### Works with standalone components?
Yes. Angular 17+ standalone API, signals, the new control flow — floors.js doesn't care about your component architecture. It only tracks URL changes at the browser level.

### Can I load it conditionally?
Yes. You can dynamically inject the script tag from a component's `ngOnInit` or `afterNextRender` if you want to load floors.js only for certain users or environments.

### Explore more
- [Add to React](/content/integrations/react/index.html)
- [Add to Vue](/content/integrations/vue/index.html)
- [floors.js for SaaS](/content/use-cases/saas/index.html)
- [floors.js for Documentation](/content/use-cases/documentation/index.html)

## Alternatives & Comparisons
- [Intercom Alternative](/content/alternatives/intercom/index.html)
- [Crisp Alternative](/content/alternatives/crisp/index.html)
- [Tidio Alternative](/content/alternatives/tidio/index.html)
- [tawk.to Alternative](/content/alternatives/tawk-to/index.html)
- [vs Gather](/content/vs/gather/index.html)
- [vs SpatialChat](/content/vs/spatial-chat/index.html)
