In this section
Resources / Installation / Frameworks
Add the embed snippet to index.html or load it once from the root standalone component so Angular’s router keeps Hubbo running.
Angular apps use a single HTML shell and client-side routing. Put the Hubbo snippet in src/index.html, or load it once from the root standalone component so it is not inserted twice. The examples match Angular 17+ (standalone is the default scaffold).
Open src/index.html and add the snippet inside <head>:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
<base href="/" />
<script src="https://api.hubbo.io/embed?key=ACCOUNT_KEY" id="hubbo-embed-script" async type="module" crossorigin="use-credentials"></script>
</head>
<body>
<app-root></app-root>
</body>
</html>If you cannot edit the HTML shell, inject the script once when the app starts. Keep your existing imports / template and only add the browser check + script inject:
import { Component, OnInit, PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
template: `<router-outlet />`,
})
export class App implements OnInit {
private readonly platformId = inject(PLATFORM_ID);
ngOnInit() {
if (!isPlatformBrowser(this.platformId)) return;
if (document.getElementById('hubbo-embed-script')) return;
const script = document.createElement('script');
script.src = 'https://api.hubbo.io/embed?key=ACCOUNT_KEY';
script.type = 'module';
script.async = true;
script.crossOrigin = 'use-credentials';
script.id = 'hubbo-embed-script';
document.body.appendChild(script);
}
}Angular router
The Hubbo embed listens to History API navigations. Angular’s router works without a full reload, and NPS, survey and notification URL rules follow the current browser location.
NgModule apps
On older NgModule projects, put the same ngOnInit body on AppComponent and inject PLATFORM_ID via the constructor instead of inject(). Prefer migrating new work to standalone.
SSR / Angular Universal
Only load the script in the browser (isPlatformBrowser). Do not append it during server rendering.