October 26, 2026

How to Add Live Chat to Angular: index.html and Service Setup

Add live chat to Angular: a code editor with a script tag and a chat bubble on a web application

To add live chat to Angular, you load one asynchronous script in the browser, once, from a place that stays alive while visitors move between routes. In practice that means a script tag in src/index.html or a small service that appends the script after the application starts. There is no package to install and no module to import, and the whole job usually takes about ten minutes. This guide shows both setups with code, explains how to keep the site key in an environment file, and covers the Angular-specific details that cause trouble: server-side rendering, router navigation, content security policy and signed-in users.

The examples use Talkmio, where the widget is a single script that loads from your site key. The same approach works for most chat widgets, but the key and address below are specific to Talkmio.

What You Need Before You Start

Create an account at app.talkmio.com; the Free plan needs no card. Open Websites, add your site and copy the site key. That key is public by design, because it appears in the page source for every visitor, so it is configuration rather than a secret. If you have a staging environment, add it as a second website with its own key so that test conversations never mix with real customers.

You also need an Angular project that you can build and serve locally. The steps work with a standalone application or one that still uses modules, and with any recent version of the framework, because the chat script runs in the visitor’s browser and not in your build tooling. If you work with other frameworks, our guides for Next.js and React and for Vue and Nuxt follow the same logic with different file names.

Why Angular Needs a Little Care

A classic website reloads the page on every navigation, so a script before the closing body tag runs again each time. Angular behaves differently. The browser loads index.html once, the application bootstraps inside the app-root element, and the router then swaps components without a full page reload. That is fast for visitors, but it means a chat script has to be loaded once and left alone. Three properties of the framework matter:

  • One host page. Everything outside app-root in index.html is served once and never re-rendered. A script placed there loads a single time for the whole visit.
  • Client-side routing. Components are created and destroyed as visitors move between routes. A script added from a routed component can be duplicated or lost, while one added from the root component or the host page is stable.
  • Server-side rendering. If you use server rendering, components run on the server first, where there is no real browser window. Code that touches the document must run only in the browser.

With those three in mind, the two options are straightforward. Pick one and stay with it.

How to Add Live Chat to Angular in index.html

The simplest option is the host page. Every Angular CLI project has a file called src/index.html that wraps the whole application. Open it and paste the Talkmio snippet before the closing body tag, after the app-root element:

<body>
  <app-root></app-root>
  <script src="https://app.talkmio.com/w/YOUR_SITE_KEY.js" async></script>
</body>

Replace YOUR_SITE_KEY with your own key. Your template may contain other tags, such as a base element or a noscript notice, so keep what is already there and add only the script line. Start the development server, open the site and the chat bubble should appear in the corner.

This works because the host page is served once with the first request. Angular’s router never reloads it, so the widget stays loaded and keeps the visitor’s conversation open as they browse. The script is asynchronous, so it does not block rendering. Do not add the address to the scripts array in angular.json: that array bundles local files into the build and is not meant for scripts that live on another server.

The trade-off is that the key is hard-coded in the template. That is fine for a single site, but if you use a different key for staging, you need either a build step that replaces the value or the second option below.

Loading the Widget from a Service

The second option puts the loader in a small service that the root component calls once. It reads the key from your environment file and appends the script in the browser:

import { Injectable, inject, PLATFORM_ID } from '@angular/core';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { environment } from '../environments/environment';

@Injectable({ providedIn: 'root' })
export class ChatLoader {
  private doc = inject(DOCUMENT);
  private platform = inject(PLATFORM_ID);

  load(): void {
    if (!isPlatformBrowser(this.platform)) return;
    if (this.doc.getElementById('talkmio-widget')) return;
    const s = this.doc.createElement('script');
    s.id = 'talkmio-widget';
    s.src = `https://app.talkmio.com/w/${environment.talkmioKey}.js`;
    s.async = true;
    this.doc.body.appendChild(s);
  }
}

Then call it from the root component, once, after the application starts:

export class AppComponent {
  constructor() {
    inject(ChatLoader).load();
  }
}

Three details make this safe. The platform check stops server rendering from touching the document. The id check prevents a second copy if the root component is ever created twice, for example in a test. And the environment file lets every build use its own key. In recent versions the environment files are not created by default; the command ng generate environments adds them, with a development and a production file that the build swaps automatically. Add a property called talkmioKey to each.

Which Option Should You Choose?

Both options end with the same widget. The table summarises the practical differences.

Question Script in index.html Loader service
Effort One line About twenty lines
Key per environment Needs a build step Environment files
Works with server rendering Yes, in the template Yes, with the platform check
Wait for cookie consent Not directly Easy to gate with a condition
Risk of double loading None None, thanks to the id check

If you have one site and no consent banner, use index.html. If you have staging and production, or you must wait for consent before loading third-party scripts, use the service. Teams that follow the general approach in our guide to adding live chat to any website usually start with the first option and move to the second when the project grows.

Identify Signed-In Users

If your Angular application has accounts, your team will find chats more useful when they see who is writing. Talkmio reads a small global object with the name and e-mail of the signed-in user, which must be set before the widget script loads:

(window as any).__TALKMIO_USER__ = { name: 'Anna Example', email: '[email protected]' };

In the loader service, set this just before you append the script, using the user from your authentication service. If the user signs in after the page has loaded, a reload after login is the simplest way to make the name appear in the Inbox. Never put anything sensitive in this object, and tell agents in your instructions never to ask visitors for passwords or payment details in chat.

Cookie Consent and Privacy

If you gate third-party scripts behind a consent banner, do not paste the script into index.html. Use the loader service and call load() only when your consent state allows it, so that the widget appears after the visitor agrees. Our guide to chat widgets, cookies and consent explains what to consider, and your own legal adviser should confirm what applies to your audience.

Talkmio stores data on servers in the EU (Germany). Only the conversation text and relevant knowledge base excerpts go to the AI model provider, and you can export or delete your data at any time. Mention the chat in your privacy notice so visitors know what happens to their messages.

Content Security Policy and Production Builds

A content security policy tells the browser which sources it may load scripts from. If your host sends one, allow scripts and connections from app.talkmio.com, or the browser will block the widget and the bubble will not appear. Angular also supports a nonce for inline styles through the ngCspNonce attribute on the root element, which is worth adding if your policy is strict. Check the browser console on a production build: a blocked script is reported there with the directive that caused it.

Test on a production build rather than only on the development server. Run ng build, serve the output folder with any static server and click through a few routes. The development server hides problems that appear after bundling, such as a missing environment replacement or a policy that only exists on the production host. Also check page speed: the script is asynchronous and small, but our article on live chat widget page speed shows how to measure the effect on your own pages.

Teach Mio After the Widget Is Live

Installing the script is the easy part. The chat becomes useful when Mio knows your product. Open Mio AI, add your website as a source, and add the documents that visitors ask about, such as price lists, setup guides and policy pages. Mio reads your website, FAQ and uploaded files (PDF, DOCX, TXT, MD, CSV, HTML) and answers only from that content, so it never invents prices or policies. Single-page applications deserve one extra check: if your content is rendered entirely in the browser, add the key pages as text, Q&A pairs or files so that Mio does not depend on what a crawler can read.

Write business instructions that say what you sell, the tone to use and what Mio must never promise. Then use Try Mio to ask the questions your customers ask and see which knowledge pieces each answer used. Visitors can write in any language, and Mio replies in theirs.

Launch Checklist

  • Create the account, add the website and copy the site key.
  • Choose one option: the script in index.html or the loader service.
  • Keep the key in environment files if you use more than one environment.
  • Check the server-rendering path, the consent rules and the content security policy.
  • Build for production, serve the output and click through several routes.
  • Add your website as a source in Mio AI and test real questions in Try Mio.

If something does not appear, open the browser console first. A blocked script, a wrong key or a policy error is almost always visible there. The documentation covers the rest of the setup, including widget colours, position, business hours and the pre-chat form.

Frequently Asked Questions

Do I need an npm package to add live chat to Angular?

No. The Talkmio widget is a single script that loads from your site key, so you either paste it into index.html or append it from a small service. Nothing is imported into your modules, which keeps the bundle unchanged and avoids version conflicts when you upgrade Angular.

Where should the script go in an Angular project?

Put it in src/index.html before the closing body tag, after app-root, or load it from a service called once by the root component. Both stay loaded while the router changes routes. Avoid adding it from routed components, because they are created and destroyed during navigation.

Does the chat widget work with Angular server-side rendering?

Yes, as long as the script is added only in the browser. In the service option, check the platform before touching the document, so server rendering never runs the loader. The script in index.html is plain markup and is also safe, because it simply sits in the served page.

Can I use a different site key for staging and production?

Yes. Add each environment as its own website in Talkmio, so each has its own key, and store the keys in the environment files. The build then replaces the right value for each target, and test conversations never reach your real inbox or reports.

How do I show the signed-in user’s name in the Inbox?

Set the global user object with name and e-mail before the widget script loads, using the user from your authentication service. If the visitor signs in later, a reload after login makes the name appear. Never include passwords, tokens or other sensitive data in that object.

Why does the chat bubble not appear after I add the script?

Open the browser console on the page. Common causes are a wrong site key, a content security policy that blocks app.talkmio.com, a template change that your build did not pick up, or a consent rule that never fires. Fix the reported cause and reload.

The Bottom Line

To add live chat to Angular you need one asynchronous script, loaded once from index.html or from a small service, plus a few checks for server rendering, consent and content security policy. The harder and more valuable work is teaching Mio your content and deciding who answers when a person is needed. Create a free Talkmio account, paste the snippet and ask Mio the first three questions your customers always ask.


Try Talkmio on your site

Free plan, no card required.

Start free