Injecting Javascript with Sharepoint Framework Extensions (Preview) - Azure Application Insights

First than all, remember that this feature is in preview, therefore the code I show here might change in the future, keep an eye on the official documentation in case you want to compile this for future builds of Sharepoint Framework Extensions.

On the Getting Started page from the official documentation, it shows how to add a div in the header placeholder and footer placeholder, however if you try to add javascript code there, it wont work, so what I tried first was the following, the code had no exceptions but it wasnt executed, and I had no STATS on the App Insights account, so my first try according to the documentation was this.

Official documentation:

  public onRender(): void {
    console.log('Available placeholders: ',
    this.context.placeholders.placeholderNames.join(', '));
    // Handling header place holder
    if (!this._headerPlaceholder) {
        this._headerPlaceholder = this.context.placeholders.tryAttach(
          onDispose: this._onDispose

      // The extension should not assume that the expected placeholder is available.
      if (!this._headerPlaceholder) {
        console.error('The expected placeholder was not found.');

      if ( {
        let headerString: string =;
        if (!headerString) {
          headerString = '(Header property was not defined.)';

        if (this._headerPlaceholder.domElement) {
          //this._headerPlaceholder.domElement.innerHTML = html;

Then I checked App Insights and I was not getting any hits.

My first thoughts is that if the code is not executed before the end head tag, then it wouldnt work.

However I found this code from another great MVP, Michael Svenson here:

If you analyze his code to execute javascript is quite large and complex, everything is done in the execute script method here:

So I did my own analysis of his great code, and was able to come to a smaller code for the problem I was trying to solve.

  public onRender(): void {
    let html: string = '';
    html+= `var appInsights=window.appInsights||function(config){
              function i(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s="AuthenticatedUserContext",h="start",c="stop",l="Track",a=l+"Event",v=l+"Page",y=u.createElement(o),r,f;y.src=config.url||"";u.getElementsByTagName(o)[0].parentNode.appendChild(y);try{t.cookie=u.cookie}catch(p){}for(t.queue=[],t.version="1.0",r=["Event","Exception","Metric","PageView","Trace","Dependency"];r.length;)i("track"+r.pop());return i("set"+s),i("clear"+s),i(h+a),i(c+a),i(h+v),i(c+v),i("flush"),config.disableExceptionTracking||(r="onerror",i("_"+r),f=e[r],e[r]=function(config,i,u,e,o){var s=f&&f(config,i,u,e,o);return s!==!0&&t["_"+r](config,i,u,e,o),s}),t
                  enableDebug: true,
    let head: any = document.getElementsByTagName("head")[0] || document.documentElement,
    script = document.createElement("script");
    script.type = "text/javascript";

    try {
        // doesn't work on ie...
        console.log('Append child');
    catch (e) {
        // IE has funky script nodes
        console.log('Append child catch');
        script.text = html;

    console.log('Right before inserting');
    head.insertBefore(script, head.firstChild);
    console.log('Before executing');

The code is self explanatory and really straightforward.

And then, the end result is that my stats works.

One suggestion for the Product Group is that there should be another place holder, to put things before the end of the head element, in that way, the first code I tried here should work as well.