diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index a781efcb72a4905395bcb4852804bfbafc9765f7..59d7751b8340a5bfa5004369d4f3adeebadfae4a 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -1,4 +1,4 @@
-import { Component, HostBinding, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, OnDestroy, ElementRef, ComponentRef, AfterViewInit, OnInit, HostListener, Renderer2, TemplateRef } from "@angular/core";
+import { Component, HostBinding, ViewChild, ViewContainerRef, OnDestroy, ElementRef, OnInit, HostListener, TemplateRef } from "@angular/core";
 import { Store, select } from "@ngrx/store";
 import { ViewerStateInterface, isDefined, FETCHED_SPATIAL_DATA, UPDATE_SPATIAL_DATA, TOGGLE_SIDE_PANEL, safeFilter } from "../services/stateStore.service";
 import { Observable, Subscription, combineLatest } from "rxjs";
@@ -7,12 +7,11 @@ import { AtlasViewerDataService } from "./atlasViewer.dataService.service";
 import { WidgetServices } from "./widgetUnit/widgetService.service";
 import { LayoutMainSide } from "../layouts/mainside/mainside.component";
 import { Chart } from 'chart.js'
-import { AtlasViewerConstantsServices, SUPPORT_LIBRARY_MAP } from "./atlasViewer.constantService.service";
+import { AtlasViewerConstantsServices } from "./atlasViewer.constantService.service";
 import { BsModalService } from "ngx-bootstrap/modal";
 import { ModalUnit } from "./modalUnit/modalUnit.component";
 import { AtlasViewerURLService } from "./atlasViewer.urlService.service";
 import { AtlasViewerAPIServices } from "./atlasViewer.apiService.service";
-import { PluginServices } from "./atlasViewer.pluginService.service";
 
 import '../res/css/extra_styles.css'
 import { NehubaContainer } from "../ui/nehubaContainer/nehubaContainer.component";
@@ -29,19 +28,18 @@ import { colorAnimation } from "./atlasViewer.animation"
   ]
 })
 
-export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
+export class AtlasViewer implements OnDestroy, OnInit {
 
-  @ViewChild('dockedContainer', { read: ViewContainerRef }) dockedContainer: ViewContainerRef
-  @ViewChild('floatingContainer', { read: ViewContainerRef }) floatingContainer: ViewContainerRef
   @ViewChild('databrowser', { read: ElementRef }) databrowser: ElementRef
-  @ViewChild('toastContainer', { read: ViewContainerRef }) toastContainer: ViewContainerRef
   @ViewChild('floatingMouseContextualContainer', { read: ViewContainerRef }) floatingMouseContextualContainer: ViewContainerRef
-  @ViewChild('pluginFactory', { read: ViewContainerRef }) pluginViewContainerRef: ViewContainerRef
   @ViewChild('helpComponent', {read: TemplateRef}) helpComponent : TemplateRef<any>
   @ViewChild(LayoutMainSide) layoutMainSide: LayoutMainSide
 
   @ViewChild(NehubaContainer) nehubaContainer: NehubaContainer
 
+  /**
+   * required for styling of all child components
+   */
   @HostBinding('attr.darktheme')
   darktheme: boolean = false
 
@@ -51,7 +49,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   private newViewer$: Observable<any>
 
   public selectedPOI$ : Observable<any[]>
-
   public showHelp$: Observable<any>
 
   public dedicatedView$: Observable<string | null>
@@ -72,8 +69,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   }
 
   constructor(
-    private pluginService: PluginServices,
-    private rd2: Renderer2,
     private store: Store<ViewerStateInterface>,
     public dataService: AtlasViewerDataService,
     private widgetServices: WidgetServices,
@@ -174,59 +169,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   }
 
   ngOnInit() {
-
-    this.apiService.interactiveViewer.pluginControl.loadExternalLibraries = (libraries: string[]) => new Promise((resolve, reject) => {
-      const srcHTMLElement = libraries.map(libraryName => ({
-        name: libraryName,
-        srcEl: SUPPORT_LIBRARY_MAP.get(libraryName)
-      }))
-
-      const rejected = srcHTMLElement.filter(scriptObj => scriptObj.srcEl === null)
-      if (rejected.length > 0)
-        return reject(`Some library names cannot be recognised. No libraries were loaded: ${rejected.map(srcObj => srcObj.name).join(', ')}`)
-
-      Promise.all(srcHTMLElement.map(scriptObj => new Promise((rs, rj) => {
-        if('customElements' in window && scriptObj.name === 'webcomponentsLite'){
-          return rs()
-        }
-        const existingEntry = this.apiService.loadedLibraries.get(scriptObj.name)
-        if (existingEntry) {
-          this.apiService.loadedLibraries.set(scriptObj.name, { counter: existingEntry.counter + 1, src: existingEntry.src })
-          rs()
-        } else {
-          const srcEl = scriptObj.srcEl
-          srcEl.onload = () => rs()
-          srcEl.onerror = (e: any) => rj(e)
-          this.rd2.appendChild(document.head, srcEl)
-          this.apiService.loadedLibraries.set(scriptObj.name, { counter: 1, src: srcEl })
-        }
-      })))
-        .then(() => resolve())
-        .catch(e => (console.warn(e), reject(e)))
-    })
-
-    this.apiService.interactiveViewer.pluginControl.unloadExternalLibraries = (libraries: string[]) =>
-      libraries
-        .filter((stringname) => SUPPORT_LIBRARY_MAP.get(stringname) !== null)
-        .forEach(libname => {
-          const ledger = this.apiService.loadedLibraries.get(libname!)
-          if (!ledger) {
-            console.warn('unload external libraries error. cannot find ledger entry...', libname, this.apiService.loadedLibraries)
-            return
-          }
-          if (ledger.src === null) {
-            console.log('webcomponents is native supported. no library needs to be unloaded')
-            return
-          }
-
-          if (ledger.counter - 1 == 0) {
-            this.rd2.removeChild(document.head, ledger.src)
-            this.apiService.loadedLibraries.delete(libname!)
-          } else {
-            this.apiService.loadedLibraries.set(libname!, { counter: ledger.counter - 1, src: ledger.src })
-          }
-        })
-
     this.meetsRequirement = this.meetsRequirements()
 
     this.subscriptions.push(
@@ -339,18 +281,13 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     })
   }
 
+  /**
+   * For completeness sake. Root element should never be destroyed. 
+   */
   ngOnDestroy() {
     this.subscriptions.forEach(s => s.unsubscribe())
   }
 
-  ngAfterViewInit() {
-    this.widgetServices.floatingContainer = this.floatingContainer
-    this.widgetServices.dockedContainer = this.dockedContainer
-
-    this.pluginService.pluginViewContainerRef = this.pluginViewContainerRef
-    this.pluginService.appendSrc = (src: HTMLElement) => this.rd2.appendChild(document.head, src)
-  }
-
   /**
    * perhaps move this to constructor?
    */
@@ -358,9 +295,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
     const canvas = document.createElement('canvas')
     const gl = canvas.getContext('webgl2') as WebGLRenderingContext
-    const message: any = {
-      Error: this.constantsService.minReqModalHeader
-    }
 
     if (!gl) {
       return false
@@ -407,20 +341,9 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     })
   }
 
-  mousePos: [number, number] = [0, 0]
-
-  @HostListener('mousemove', ['$event'])
-  mousemove(event: MouseEvent) {
-    this.mousePos = [event.clientX, event.clientY]
-  }
-
   @HostBinding('attr.version')
   public _version : string = VERSION
 
-  get floatingMouseContextualContainerTransform() {
-    return `translate(${this.mousePos[0]}px,${this.mousePos[1]}px)`
-  }
-
   get isMobile(){
     return this.constantsService.mobile
   }
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index 9cbaa9666527c4dedab2b2a732d08082feb3002f..04f4b488d98fe01ee01a4995318e2a49067c9e7c 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -74,7 +74,10 @@
       </div>
       
       <!-- Docked Container-->
-      <div dockedContainer #dockedContainer>
+      <div dockedContainer>
+        <div dockedContainerDirective>
+
+        </div>
       </div>
     </div>
 
@@ -148,10 +151,10 @@
   <layout-floating-container
     zIndex = "9"
     #floatingOverlayContainer>
-    <ng-template #floatingContainer>
+    <div floatingContainerDirective>
 
-    </ng-template>
-    <div [style.transform] = "floatingMouseContextualContainerTransform" floatingMouseContextualContainer>
+    </div>
+    <div floatingMouseContextualContainer floatingMouseContextualContainerDirective>
       <div 
         *ngIf = "onhoverLandmark$ | async" 
         contextualBlock>
@@ -170,8 +173,9 @@
     </div>
   </layout-floating-container>
 
-  <ng-template #pluginFactory>
-  </ng-template>
+  <div pluginFactoryDirective>
+
+  </div>
 
 </div>
 
diff --git a/src/main.module.ts b/src/main.module.ts
index 5dfe69c06548a3f5719791c6c31b7010de945b6e..e04add7c374f89020a29e6d011139fd397433b64 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -28,6 +28,10 @@ import { ToastService } from "./services/toastService.service";
 import { AtlasWorkerService } from "./atlasViewer/atlasViewer.workerService.service";
 import { HelpDirective } from "./util/directives/help.directive";
 import { ToastContainerDirective } from "./util/directives/toastContainer.directive";
+import { DockedContainerDirective } from "./util/directives/dockedContainer.directive";
+import { FloatingContainerDirective } from "./util/directives/floatingContainer.directive";
+import { PluginFactoryDirective } from "./util/directives/pluginFactory.directive";
+import { FloatingMouseContextualContainerDirective } from "./util/directives/floatingMouseContextualContainer.directive";
 
 @NgModule({
   imports : [
@@ -64,6 +68,10 @@ import { ToastContainerDirective } from "./util/directives/toastContainer.direct
     GlyphiconTooltipRemoveSignDirective,
     HelpDirective,
     ToastContainerDirective,
+    DockedContainerDirective,
+    FloatingContainerDirective,
+    PluginFactoryDirective,
+    FloatingMouseContextualContainerDirective,
 
     /* pipes */
     GetNamesPipe,
diff --git a/src/util/directives/dockedContainer.directive.ts b/src/util/directives/dockedContainer.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..741fa61fd3d190d1320292b4ed955919938a1749
--- /dev/null
+++ b/src/util/directives/dockedContainer.directive.ts
@@ -0,0 +1,16 @@
+import { Directive, ViewContainerRef } from "@angular/core";
+import { WidgetServices } from "src/atlasViewer/widgetUnit/widgetService.service";
+
+
+@Directive({
+  selector: '[dockedContainerDirective]'
+})
+
+export class DockedContainerDirective{
+  constructor(
+    widgetService: WidgetServices,
+    viewContainerRef: ViewContainerRef
+  ){
+    widgetService.dockedContainer = viewContainerRef
+  }
+}
\ No newline at end of file
diff --git a/src/util/directives/floatingContainer.directive.ts b/src/util/directives/floatingContainer.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..740ab815a6ebeb6a7ab1c365467136e5288daacd
--- /dev/null
+++ b/src/util/directives/floatingContainer.directive.ts
@@ -0,0 +1,15 @@
+import { Directive, ViewContainerRef } from "@angular/core";
+import { WidgetServices } from "src/atlasViewer/widgetUnit/widgetService.service";
+
+@Directive({
+  selector: '[floatingContainerDirective]'
+})
+
+export class FloatingContainerDirective{
+  constructor(
+    widgetService: WidgetServices,
+    viewContainerRef: ViewContainerRef
+  ){
+    widgetService.floatingContainer = viewContainerRef
+  }
+}
\ No newline at end of file
diff --git a/src/util/directives/floatingMouseContextualContainer.directive.ts b/src/util/directives/floatingMouseContextualContainer.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f62b11aac7311055c9023ba1c32e83077807bbb
--- /dev/null
+++ b/src/util/directives/floatingMouseContextualContainer.directive.ts
@@ -0,0 +1,20 @@
+import { Directive, HostListener, HostBinding } from "@angular/core";
+
+@Directive({
+  selector: '[floatingMouseContextualContainerDirective]'
+})
+
+export class FloatingMouseContextualContainerDirective{
+  
+  private mousePos: [number, number] = [0, 0]
+
+  @HostListener('document:mousemove', ['$event'])
+  mousemove(event:MouseEvent){
+    this.mousePos = [event.clientX, event.clientY]
+  }
+
+  @HostBinding('style.transform')
+  get transform(){
+    return `translate(${this.mousePos[0]}px,${this.mousePos[1]}px)`
+  }
+}
\ No newline at end of file
diff --git a/src/util/directives/pluginFactory.directive.ts b/src/util/directives/pluginFactory.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..87a843b8f98a5d2dc2f51cc4505ac3bb560677fc
--- /dev/null
+++ b/src/util/directives/pluginFactory.directive.ts
@@ -0,0 +1,75 @@
+import { Directive, ViewContainerRef, Renderer2 } from "@angular/core";
+import { PluginServices } from "src/atlasViewer/atlasViewer.pluginService.service";
+import { AtlasViewerAPIServices } from "src/atlasViewer/atlasViewer.apiService.service";
+import { SUPPORT_LIBRARY_MAP } from "src/atlasViewer/atlasViewer.constantService.service";
+
+@Directive({
+  selector: '[pluginFactoryDirective]'
+})
+
+export class PluginFactoryDirective{
+  constructor(
+    pluginService: PluginServices,
+    viewContainerRef: ViewContainerRef,
+    rd2: Renderer2,
+    apiService:AtlasViewerAPIServices
+  ){
+    pluginService.pluginViewContainerRef = viewContainerRef
+    pluginService.appendSrc = (src: HTMLElement) => rd2.appendChild(document.head, src)
+
+    apiService.interactiveViewer.pluginControl.loadExternalLibraries = (libraries: string[]) => new Promise((resolve, reject) => {
+      const srcHTMLElement = libraries.map(libraryName => ({
+        name: libraryName,
+        srcEl: SUPPORT_LIBRARY_MAP.get(libraryName)
+      }))
+
+      const rejected = srcHTMLElement.filter(scriptObj => scriptObj.srcEl === null)
+      if (rejected.length > 0)
+        return reject(`Some library names cannot be recognised. No libraries were loaded: ${rejected.map(srcObj => srcObj.name).join(', ')}`)
+
+      Promise.all(srcHTMLElement.map(scriptObj => new Promise((rs, rj) => {
+        /**
+         * if browser already support customElements, do not append polyfill
+         */
+        if('customElements' in window && scriptObj.name === 'webcomponentsLite'){
+          return rs()
+        }
+        const existingEntry = apiService.loadedLibraries.get(scriptObj.name)
+        if (existingEntry) {
+          apiService.loadedLibraries.set(scriptObj.name, { counter: existingEntry.counter + 1, src: existingEntry.src })
+          rs()
+        } else {
+          const srcEl = scriptObj.srcEl
+          srcEl.onload = () => rs()
+          srcEl.onerror = (e: any) => rj(e)
+          rd2.appendChild(document.head, srcEl)
+          apiService.loadedLibraries.set(scriptObj.name, { counter: 1, src: srcEl })
+        }
+      })))
+        .then(() => resolve())
+        .catch(e => (console.warn(e), reject(e)))
+    })
+
+    apiService.interactiveViewer.pluginControl.unloadExternalLibraries = (libraries: string[]) =>
+      libraries
+        .filter((stringname) => SUPPORT_LIBRARY_MAP.get(stringname) !== null)
+        .forEach(libname => {
+          const ledger = apiService.loadedLibraries.get(libname!)
+          if (!ledger) {
+            console.warn('unload external libraries error. cannot find ledger entry...', libname, apiService.loadedLibraries)
+            return
+          }
+          if (ledger.src === null) {
+            console.log('webcomponents is native supported. no library needs to be unloaded')
+            return
+          }
+
+          if (ledger.counter - 1 == 0) {
+            rd2.removeChild(document.head, ledger.src)
+            apiService.loadedLibraries.delete(libname!)
+          } else {
+            apiService.loadedLibraries.set(libname!, { counter: ledger.counter - 1, src: ledger.src })
+          }
+        })
+  }
+}
\ No newline at end of file