Insert script tags in Angular components

Sometimes you just need to insert 3rd party script tags into Angular Components. It is definitely not very common, and Angular does not make it easy for you. What ever script tag you define your component’s template, will be simply cleared out. Not even a html comment will remain. So I you really need to insert a 3rd party script into your component, you have to do inside the javascript part.

It is actually quite simple. You create a script DOM element, set the src or innerHTML or text property and attach it to the DOM via renderer service.

// 1. import dependencies
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';

// 2. pass then in constructor
constructor(
    private renderer2: Renderer2,
    @Inject(DOCUMENT) private _document
  ) {
  }

// 3. call them in ngOnInit
ngOnInit() {
   const s = this.renderer2.createElement('script');
   s.type = 'text/javascript';
   s.src = 'https://path/to/your/script';
   s.text = ``;
   this.renderer2.appendChild(this._document.body, s);
}

But what if you have scripts, which depend on each other, and have to be called only after the previous ones has been loaded? For example you load affiliate tracker, and you need to initialize it. If you call the initialization code too soon, you will get an error. Luckily you can use the onload property of the script element, and use it to load the dependent scripts. So the final code would look something like this

// 3. call them in ngOnInit - using onload for dependencies
ngOnInit() {
   const s = this.renderer2.createElement('script');
   s.onload = this.loadNextScript.bind(this);
   s.type = 'text/javascript';
   s.src = 'https://path/to/your/script'; // Defines someGlobalObject
   s.text = ``;
   this.renderer2.appendChild(this._document.body, s);
}

loadNextScript() {
   const s = this.renderer2.createElement('script');
   s.text = `
   // This would error, if previous script has not yet been loaded
    someGlobalObject.doSomething();
`
   this.renderer2.appendChild(this._document.body, s);
}

Happy coding. Hope this helped someone

debugging

What to read more?

Dive deeper into Angular Components in this article on Toptal blog. How to use them, difference between components and directives, performance etc.