diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index 26ab547fab0cdd5e17f44785dfbea94665e3fa8f..aea9618aa57060e40a6333322834bbadb14220c3 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -1,5 +1,5 @@
 /* eslint-disable @typescript-eslint/no-empty-function */
-import {Injectable, NgZone, Optional, Inject, OnDestroy} from "@angular/core";
+import {Injectable, NgZone, Optional, Inject, OnDestroy, InjectionToken} from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { Observable, Subject, Subscription, from, race, of, } from "rxjs";
 import { distinctUntilChanged, map, filter, startWith, switchMap, catchError, mapTo } from "rxjs/operators";
@@ -446,3 +446,9 @@ export const overrideNehubaClickFactory = (apiService: AtlasViewerAPIServices, g
     next()
   }
 }
+
+export const API_SERVICE_SET_VIEWER_HANDLE_TOKEN = new InjectionToken<(viewerHandle) => void>('API_SERVICE_SET_VIEWER_HANDLE_TOKEN')
+
+export const setViewerHandleFactory = (apiService: AtlasViewerAPIServices) => {
+  return viewerHandle => apiService.interactiveViewer.viewerHandle = viewerHandle
+}
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index 454a2c9338880b08da7262b4fa279d136bb637e4..f435d07bed178da1c42a14bb1af88ca84818a4ed 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -1,16 +1,12 @@
 import { HttpClient, HttpHeaders } from "@angular/common/http";
 import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { merge, Observable, of, Subscription, throwError, fromEvent, forkJoin } from "rxjs";
-import { catchError, map, shareReplay, switchMap, tap, filter, take } from "rxjs/operators";
-import { LoggingService } from "src/logging";
+import { Observable, Subscription } from "rxjs";
+import { map, shareReplay } from "rxjs/operators";
 import { SNACKBAR_MESSAGE } from "src/services/state/uiState.store";
 import { IavRootStoreInterface } from "../services/stateStore.service";
-import { AtlasWorkerService } from "./atlasViewer.workerService.service";
 import { PureContantService } from "src/util";
 
-const getUniqueId = () => Math.round(Math.random() * 1e16).toString(16)
-
 @Injectable({
   providedIn : 'root',
 })
@@ -30,77 +26,12 @@ export class AtlasViewerConstantsServices implements OnDestroy {
   // instead of using window.location.href, which includes query param etc
   public backendUrl = (BACKEND_URL && `${BACKEND_URL}/`.replace(/\/\/$/, '/')) || `${window.location.origin}${window.location.pathname}`
 
-  private fetchTemplate = (templateUrl) => this.http.get(`${this.backendUrl}${templateUrl}`, { responseType: 'json' }).pipe(
-    switchMap((template: any) => {
-      if (template.nehubaConfig) { return of(template) }
-      if (template.nehubaConfigURL) { return this.http.get(`${this.backendUrl}${template.nehubaConfigURL}`, { responseType: 'json' }).pipe(
-        map(nehubaConfig => {
-          return {
-            ...template,
-            nehubaConfig,
-          }
-        }),
-      )
-      }
-      throwError('neither nehubaConfig nor nehubaConfigURL defined')
-    }),
-  )
-
   public totalTemplates = null
 
-  private workerUpdateParcellation$ = fromEvent(this.workerService.worker, 'message').pipe(
-    filter((message: MessageEvent) => message && message.data && message.data.type === 'UPDATE_PARCELLATION_REGIONS'),
-    map(({ data }) => data)
-  )
-
-  private processTemplate = template => forkJoin(
-    ...template.parcellations.map(parcellation => {
-
-      const id = getUniqueId()
-
-      this.workerService.worker.postMessage({
-        type: 'PROPAGATE_PARC_REGION_ATTR',
-        parcellation,
-        inheritAttrsOpts: {
-          ngId: (parcellation as any ).ngId,
-          relatedAreas: [],
-          fullId: null
-        },
-        id
-      })
-
-      return this.workerUpdateParcellation$.pipe(
-        filter(({ id: returnedId }) => id === returnedId),
-        take(1),
-        map(({ parcellation }) => parcellation)
-      )
-    })
-  )
-
   public getTemplateEndpoint$ = this.http.get(`${this.backendUrl}templates`, { responseType: 'json' }).pipe(
     shareReplay(1)
   )
 
-  public initFetchTemplate$ = this.getTemplateEndpoint$.pipe(
-    tap((arr: any[]) => this.totalTemplates = arr.length),
-    switchMap((templates: string[]) => merge(
-      ...templates.map(templateName => this.fetchTemplate(templateName).pipe(
-        switchMap(template => this.processTemplate(template).pipe(
-          map(parcellations => {
-            return {
-              ...template,
-              parcellations
-            }
-          })
-        ))
-      )),
-    )),
-    catchError((err) => {
-      this.log.warn(`fetching templates error`, err)
-      return of(null)
-    }),
-  )
-
   public templateUrls = Array(100)
 
   /* to be provided by KG in future */
@@ -258,8 +189,6 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
   constructor(
     private store$: Store<IavRootStoreInterface>,
     private http: HttpClient,
-    private log: LoggingService,
-    private workerService: AtlasWorkerService,
     private pureConstantService: PureContantService
   ) {
 
@@ -291,7 +220,10 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
           this.dissmissUserLayerSnackbarMessage = this.dissmissUserLayerSnackbarMessageDesktop
         }
       }),
-    )
+    ),
+    this.pureConstantService.getTemplateEndpoint$.subscribe(arr => {
+      this.totalTemplates = arr.length
+    })
   }
 
   private subscriptions: Subscription[] = []
diff --git a/src/main.module.ts b/src/main.module.ts
index c55025199c41b7e7c32a17da846975f26f86fd96..0c274937627d74c3498016649b6aab73c2b5f55c 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -14,7 +14,7 @@ import { GetNamesPipe } from "./util/pipes/getNames.pipe";
 
 import { HttpClientModule } from "@angular/common/http";
 import { EffectsModule } from "@ngrx/effects";
-import { AtlasViewerAPIServices, overrideNehubaClickFactory, CANCELLABLE_DIALOG, GET_TOAST_HANDLER_TOKEN } from "./atlasViewer/atlasViewer.apiService.service";
+import { AtlasViewerAPIServices, overrideNehubaClickFactory, CANCELLABLE_DIALOG, GET_TOAST_HANDLER_TOKEN, API_SERVICE_SET_VIEWER_HANDLE_TOKEN, setViewerHandleFactory } from "./atlasViewer/atlasViewer.apiService.service";
 import { AtlasWorkerService } from "./atlasViewer/atlasViewer.workerService.service";
 import { ModalUnit } from "./atlasViewer/modalUnit/modalUnit.component";
 import { TransformOnhoverSegmentPipe } from "./atlasViewer/onhoverSegment.pipe";
@@ -252,12 +252,17 @@ export const GET_STATE_SNAPSHOT_TOKEN = new InjectionToken('GET_STATE_SNAPSHOT_T
       provide: TOS_OBS_INJECTION_TOKEN,
       useFactory: (dbService: DatabrowserService) => dbService.kgTos$,
       deps: [ DatabrowserService ]
-    }
+    },
 
     /**
      * TODO
      * once nehubacontainer is separated into viewer + overlay, migrate to nehubaContainer module
      */
+    {
+      provide: API_SERVICE_SET_VIEWER_HANDLE_TOKEN,
+      useFactory: setViewerHandleFactory,
+      deps: [ AtlasViewerAPIServices ]
+    },
   ],
   bootstrap : [
     AtlasViewer,
diff --git a/src/services/effect/pluginUseEffect.ts b/src/services/effect/pluginUseEffect.ts
index 5a28ace68c9c20e5867d70ebff2ad8e46e983e6e..1c60a3d5a99fb8a758aeeaf318308330cf23794f 100644
--- a/src/services/effect/pluginUseEffect.ts
+++ b/src/services/effect/pluginUseEffect.ts
@@ -6,7 +6,6 @@ import { filter, map, startWith, switchMap } from "rxjs/operators"
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service"
 import { PluginServices } from "src/atlasViewer/pluginUnit"
 import { PLUGINSTORE_ACTION_TYPES, PLUGINSTORE_CONSTANTS } from 'src/services/state/pluginState.store'
-import { LoggingService } from "src/logging"
 import { IavRootStoreInterface } from "../stateStore.service"
 import { HttpClient } from "@angular/common/http"
 
@@ -23,7 +22,6 @@ export class PluginServiceUseEffect {
     store$: Store<IavRootStoreInterface>,
     constantService: AtlasViewerConstantsServices,
     pluginService: PluginServices,
-    private log: LoggingService,
     http: HttpClient
   ) {
     this.initManifests$ = store$.pipe(
diff --git a/src/services/state/viewerState.store.helper.ts b/src/services/state/viewerState.store.helper.ts
index 6405a55b39509fbe3a6315d24ff0d332af115a95..de45f8a073249ff6c2d2de0b7b9505fb02fb58bb 100644
--- a/src/services/state/viewerState.store.helper.ts
+++ b/src/services/state/viewerState.store.helper.ts
@@ -7,6 +7,7 @@ import { withLatestFrom, map } from "rxjs/operators";
 import { Injectable } from "@angular/core";
 
 import {
+  viewerStateNewViewer,
   viewerStateHelperSelectParcellationWithId,
   viewerStateNavigateToRegion,
   viewerStateRemoveAdditionalLayer,
@@ -22,10 +23,14 @@ import {
   viewerStateSelectRegionWithIdDeprecated,
   viewerStateDblClickOnViewer,
   viewerStateAddUserLandmarks,
-  viewreStateRemoveUserLandmarks
+  viewreStateRemoveUserLandmarks,
+  viewerStateMouseOverCustomLandmark,
+  viewerStateMouseOverCustomLandmarkInPerspectiveView,
+  viewerStateSelectTemplateWithName,
 } from './viewerState/actions'
 
 export {
+  viewerStateNewViewer,
   viewerStateHelperSelectParcellationWithId,
   viewerStateNavigateToRegion,
   viewerStateRemoveAdditionalLayer,
@@ -41,7 +46,10 @@ export {
   viewerStateSelectRegionWithIdDeprecated,
   viewerStateDblClickOnViewer,
   viewerStateAddUserLandmarks,
-  viewreStateRemoveUserLandmarks
+  viewreStateRemoveUserLandmarks,
+  viewerStateMouseOverCustomLandmark,
+  viewerStateMouseOverCustomLandmarkInPerspectiveView,
+  viewerStateSelectTemplateWithName,
 }
 
 import {
@@ -50,6 +58,8 @@ import {
   viewerStateSelectedParcellationSelector,
   viewerStateGetSelectedAtlas,
   viewerStateCustomLandmarkSelector,
+  viewerStateFetchedTemplatesSelector,
+  viewerStateNavigationStateSelector,
 } from './viewerState/selectors'
 
 export {
@@ -57,6 +67,8 @@ export {
   viewerStateSelectedTemplateSelector,
   viewerStateSelectedParcellationSelector,
   viewerStateCustomLandmarkSelector,
+  viewerStateFetchedTemplatesSelector,
+  viewerStateNavigationStateSelector,
 }
 
 interface IViewerStateHelperStore{
diff --git a/src/services/state/viewerState.store.ts b/src/services/state/viewerState.store.ts
index 0060ef7b39b1644b9d2211648fd7ef85cf88a914..63fefee549b4b6366197ef7e66e19d0a249f1379 100644
--- a/src/services/state/viewerState.store.ts
+++ b/src/services/state/viewerState.store.ts
@@ -17,9 +17,14 @@ import {
   viewerStateSelectParcellation,
   viewerStateSelectRegionWithIdDeprecated,
   viewerStateCustomLandmarkSelector,
+  viewerStateDblClickOnViewer,
+  viewerStateAddUserLandmarks,
+  viewreStateRemoveUserLandmarks,
+  viewerStateMouseOverCustomLandmark,
+  viewerStateMouseOverCustomLandmarkInPerspectiveView,
+  viewerStateNewViewer
 } from './viewerState.store.helper';
-
-import { viewerStateDblClickOnViewer, viewerStateAddUserLandmarks, viewreStateRemoveUserLandmarks, viewerStateMouseOverCustomLandmark, viewerStateMouseOverCustomLandmarkInPerspectiveView } from './viewerState/actions';
+import { cvtNehubaConfigToNavigationObj } from 'src/ui/viewerStateController/viewerState.useEffect';
 
 export interface StateInterface {
   fetchedTemplates: any[]
@@ -132,17 +137,22 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState: Part
     }
   case NEWVIEWER: {
 
-    const { selectParcellation: parcellation } = action
+    const {
+      selectParcellation: parcellation,
+      navigation,
+      selectTemplate,
+    } = action
+    const navigationFromTemplateSelected = cvtNehubaConfigToNavigationObj(selectTemplate?.nehubaConfig?.dataset?.initialNgState)
     return {
       ...prevState,
-      templateSelected : action.selectTemplate,
+      templateSelected : selectTemplate,
       parcellationSelected : parcellation,
       // taken care of by effect.ts
       // regionsSelected : [],
 
       // taken care of by effect.ts
       // landmarksSelected : [],
-      navigation : action.navigation,
+      navigation : navigation || navigationFromTemplateSelected,
       dedicatedView : null,
     }
   }
@@ -258,7 +268,7 @@ export function stateStore(state, action) {
 export const LOAD_DEDICATED_LAYER = 'LOAD_DEDICATED_LAYER'
 export const UNLOAD_DEDICATED_LAYER = 'UNLOAD_DEDICATED_LAYER'
 
-export const NEWVIEWER = 'NEWVIEWER'
+export const NEWVIEWER = viewerStateNewViewer.type
 
 export const FETCHED_TEMPLATE = 'FETCHED_TEMPLATE'
 export const CHANGE_NAVIGATION = 'CHANGE_NAVIGATION'
diff --git a/src/services/state/viewerState/actions.ts b/src/services/state/viewerState/actions.ts
index 3b19de4b1dd9f725a0b61665be6c641e52729820..4da8446635f964488249447df68329d4b77d1d57 100644
--- a/src/services/state/viewerState/actions.ts
+++ b/src/services/state/viewerState/actions.ts
@@ -1,6 +1,15 @@
 import { createAction, props } from "@ngrx/store"
 import { IRegion } from './constants'
 
+export const viewerStateNewViewer = createAction(
+  `[viewerState] newViewer`,
+  props<{ 
+    selectTemplate: any
+    selectParcellation: any
+    navigation?: any
+  }>()
+)
+
 export const viewerStateSetSelectedRegionsWithIds = createAction(
   `[viewerState] setSelectedRegionsWithIds`,
   props<{ selectRegionIds: string[] }>()
@@ -46,6 +55,11 @@ export const viewerStateSelectParcellation = createAction(
   props<{ selectParcellation: any }>()
 )
 
+export const viewerStateSelectTemplateWithName = createAction(
+  `[viewerState] selectTemplateWithName`, 
+  props<{ payload: { name: string } }>()
+)
+
 export const viewerStateSelectTemplateWithId = createAction(
   `[viewerState] selectTemplateWithId`,
   props<{ payload: { ['@id']: string }, config?: { selectParcellation: { ['@id']: string } } }>()
@@ -90,3 +104,4 @@ export const viewerStateMouseOverCustomLandmarkInPerspectiveView = createAction(
   `[viewerState] mouseOverCustomLandmarkInPerspectiveView`,
   props<{ payload: { label: string } }>()
 )
+
diff --git a/src/services/state/viewerState/selectors.ts b/src/services/state/viewerState/selectors.ts
index 8b5b442e3d11d50fd577328099057ac4af89a249..44c4c8db76f62baea9ad3a656d7fcad184ed7ad2 100644
--- a/src/services/state/viewerState/selectors.ts
+++ b/src/services/state/viewerState/selectors.ts
@@ -22,6 +22,11 @@ const flattenFetchedTemplatesIntoParcellationsReducer = (acc, curr) => {
   return acc.concat( parcelations )
 }
 
+export const viewerStateFetchedTemplatesSelector = createSelector(
+  state => state['viewerState'],
+  viewerState => viewerState['fetchedTemplates']
+)
+
 export const viewerStateSelectedTemplateSelector = createSelector(
   state => state['viewerState'],
   viewerState => viewerState['templateSelected']
@@ -32,6 +37,11 @@ export const viewerStateSelectedParcellationSelector = createSelector(
   viewerState => viewerState['parcellationSelected']
 )
 
+export const viewerStateNavigationStateSelector = createSelector(
+  state => state['viewerState'],
+  viewerState => viewerState['navigation']
+)
+
 export const viewerStateAllRegionsFlattenedRegionSelector = createSelector(
   viewerStateSelectedParcellationSelector,
   parc => {
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
index 966569fe94484d56131a535dad0d45f0413ea6cc..3e5017b97f3c820dd1637442e736a6505f4edf04 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts
@@ -3,13 +3,12 @@ import { TestBed, async, ComponentFixture, fakeAsync, tick, flush, discardPeriod
 import { NehubaContainer } from "./nehubaContainer.component"
 import { provideMockStore, MockStore } from "@ngrx/store/testing"
 import { defaultRootState } from 'src/services/stateStore.service'
-import { ComponentsModule } from "src/components"
 import { AngularMaterialModule } from "../sharedModules/angularMaterial.module"
 import { TouchSideClass } from "./touchSideClass.directive"
 import { MaximmisePanelButton } from "./maximisePanelButton/maximisePanelButton.component"
 import { LandmarkUnit } from './landmarkUnit/landmarkUnit.component'
 import { LayoutModule } from 'src/layouts/layout.module'
-import { UtilModule } from "src/util"
+import { PureContantService, UtilModule } from "src/util"
 import { AtlasLayerSelector } from "../atlasLayerSelector/atlasLayerSelector.component"
 import { StatusCardComponent } from './statusCard/statusCard.component'
 import { NehubaViewerTouchDirective } from './nehubaViewerInterface/nehubaViewerTouch.directive'
@@ -28,7 +27,6 @@ import { StateModule } from 'src/state'
 import { ReactiveFormsModule, FormsModule } from '@angular/forms'
 import { HttpClientModule } from '@angular/common/http'
 import { WidgetModule } from 'src/widget'
-import { PluginModule } from 'src/atlasViewer/pluginUnit/plugin.module'
 import { NehubaModule } from './nehuba.module'
 import { CommonModule } from '@angular/common'
 import { IMPORT_NEHUBA_INJECT_TOKEN } from './nehubaViewer/nehubaViewer.component'
@@ -39,6 +37,8 @@ import { ARIA_LABELS } from 'common/constants'
 import { NoopAnimationsModule } from '@angular/platform-browser/animations'
 import { RegionAccordionTooltipTextPipe } from '../util'
 import { hot } from 'jasmine-marbles'
+import { of } from 'rxjs'
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'
 import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from 'src/services/state/ngViewerState/selectors'
 import { PANELS } from 'src/services/state/ngViewerState/constants'
 
@@ -69,9 +69,7 @@ describe('> nehubaContainer.component.ts', () => {
       TestBed.configureTestingModule({
         imports: [
           NoopAnimationsModule,
-          PluginModule,
           WidgetModule,
-          ComponentsModule,
           AngularMaterialModule,
           LayoutModule,
           UtilModule,
@@ -82,7 +80,13 @@ describe('> nehubaContainer.component.ts', () => {
           FormsModule,
           ReactiveFormsModule,
           HttpClientModule,
-          CommonModule
+          CommonModule,
+
+          /**
+           * because the change done to pureconstant service, need to intercept http call to avoid crypto error message
+           * so and so components needs to be compiled first. make sure you call compileComponents
+           */
+          HttpClientTestingModule,
         ],
         declarations: [
           NehubaContainer,
@@ -98,7 +102,7 @@ describe('> nehubaContainer.component.ts', () => {
           CurrentLayout,
           RegionDirective,
           RegionTextSearchAutocomplete,
-
+  
           // pipes
           MobileControlNubStylePipe,
           ReorderPanelIndexPipe,
@@ -111,13 +115,15 @@ describe('> nehubaContainer.component.ts', () => {
           {
             provide: IMPORT_NEHUBA_INJECT_TOKEN,
             useValue: importNehubaSpy
-          }
+          },
+          PureContantService,
+
         ],
         schemas: [
           CUSTOM_ELEMENTS_SCHEMA
         ],
       }).compileComponents()
-
+      
     }))
 
     it('> component can be created', () => {
@@ -128,7 +134,6 @@ describe('> nehubaContainer.component.ts', () => {
     })
 
     describe('> on selectedTemplatechange', () => {
-      
       it('> calls importNehubaPr', async () => {
         const fixture = TestBed.createComponent(NehubaContainer)
         fixture.componentInstance.currentOnHoverObs$ = hot('')
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index fd0c2ba97aacc9b0ecd1d474d93e94173a6a0dac..5e13e5789c093cff93384f47b7dcb34b4291e4f3 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, ViewChild, ChangeDetectorRef, Output, EventEmitter } from "@angular/core";
+import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, ViewChild, ChangeDetectorRef, Output, EventEmitter, Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { combineLatest, fromEvent, merge, Observable, of, Subscription, timer, asyncScheduler, BehaviorSubject, Subject } from "rxjs";
 import { pipe } from "rxjs/internal/util/pipe";
@@ -20,8 +20,9 @@ import {
   MOUSE_OVER_LANDMARK,
   NgViewerStateInterface
 } from "src/services/stateStore.service";
-import { getExportNehuba, isSame } from "src/util/fn";
-import { AtlasViewerAPIServices, IUserLandmark } from "src/atlasViewer/atlasViewer.apiService.service";
+
+import { getExportNehuba, isSame, getViewer } from "src/util/fn";
+import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, IUserLandmark } from "src/atlasViewer/atlasViewer.apiService.service";
 import { NehubaViewerUnit } from "./nehubaViewer/nehubaViewer.component";
 import { compareLandmarksChanged } from "src/util/constants";
 import { PureContantService } from "src/util";
@@ -292,7 +293,7 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
 
   constructor(
     private pureConstantService: PureContantService,
-    private apiService: AtlasViewerAPIServices,
+    @Optional() @Inject(API_SERVICE_SET_VIEWER_HANDLE_TOKEN) private setViewerHandle: (arg) => void,
     private store: Store<any>,
     private elementRef: ElementRef,
     private log: LoggingService,
@@ -920,7 +921,7 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
      * TODO if plugin subscribes to viewerHandle, and then new template is selected, changes willl not be be sent
      * could be considered as a bug.
      */
-    this.apiService.interactiveViewer.viewerHandle = null
+    this.setViewerHandle && this.setViewerHandle(null)
     this.nehubaContainerDirective.clear()
 
     this.nehubaViewer = null
@@ -937,7 +938,7 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
   }
 
   private setupViewerHandleApi() {
-    this.apiService.interactiveViewer.viewerHandle = {
+    const viewerHandle = {
       setNavigationLoc : (coord, realSpace?) => this.nehubaViewer.setNavigationState({
         position : coord,
         positionReal : typeof realSpace !== 'undefined' ? realSpace : true,
@@ -1070,6 +1071,8 @@ export class NehubaContainer implements OnInit, OnChanges, OnDestroy {
       ),
       getNgHash : this.nehubaViewer.getNgHash,
     }
+
+    this.setViewerHandle && this.setViewerHandle(viewerHandle)
   }
 
   public setOctantRemoval(octantRemovalFlag: boolean) {
diff --git a/src/ui/viewerStateController/viewerState.base.ts b/src/ui/viewerStateController/viewerState.base.ts
index ee206f5bd32cad100dc63ade0f6edc1e888619f9..70a67c226bec656ba46429e5d9cd203605a5fcd9 100644
--- a/src/ui/viewerStateController/viewerState.base.ts
+++ b/src/ui/viewerStateController/viewerState.base.ts
@@ -7,9 +7,9 @@ import { RegionSelection } from "src/services/state/userConfigState.store";
 import { IavRootStoreInterface, SELECT_REGIONS, USER_CONFIG_ACTION_TYPES } from "src/services/stateStore.service";
 import { MatSelectChange } from "@angular/material/select";
 import { MatBottomSheet, MatBottomSheetRef } from "@angular/material/bottom-sheet";
+import { viewerStateSelectTemplateWithName } from "src/services/state/viewerState/actions";
 
 const ACTION_TYPES = {
-  SELECT_TEMPLATE_WITH_NAME: 'SELECT_TEMPLATE_WITH_NAME',
   SELECT_PARCELLATION_WITH_NAME: 'SELECT_PARCELLATION_WITH_NAME',
 
 }
@@ -94,13 +94,11 @@ export class ViewerStateBase implements OnInit {
   }
 
   public handleTemplateChange(event: MatSelectChange) {
-
-    this.store$.dispatch({
-      type: ACTION_TYPES.SELECT_TEMPLATE_WITH_NAME,
-      payload: {
-        name: event.value,
-      },
-    })
+    this.store$.dispatch(
+      viewerStateSelectTemplateWithName({
+        payload: { name: event.value }
+      })
+    )
   }
 
   public handleParcellationChange(event: MatSelectChange) {
diff --git a/src/ui/viewerStateController/viewerState.useEffect.spec.ts b/src/ui/viewerStateController/viewerState.useEffect.spec.ts
index 513854f6703aa76d6b5b3c2f79b9fd574c8a13d6..b1eeb09408029608558233406555263d33cf6f73 100644
--- a/src/ui/viewerStateController/viewerState.useEffect.spec.ts
+++ b/src/ui/viewerStateController/viewerState.useEffect.spec.ts
@@ -1,19 +1,20 @@
-import { ViewerStateControllerUseEffect } from './viewerState.useEffect'
+import { cvtNavigationObjToNehubaConfig, cvtNehubaConfigToNavigationObj, ViewerStateControllerUseEffect, defaultNavigationObject, defaultNehubaConfigObject } from './viewerState.useEffect'
 import { Observable, of } from 'rxjs'
 import { TestBed, async } from '@angular/core/testing'
 import { provideMockActions } from '@ngrx/effects/testing'
-import { provideMockStore } from '@ngrx/store/testing'
+import { MockStore, provideMockStore } from '@ngrx/store/testing'
 import { defaultRootState, NEWVIEWER } from 'src/services/stateStore.service'
 import { Injectable } from '@angular/core'
 import { TemplateCoordinatesTransformation, ITemplateCoordXformResp } from 'src/services/templateCoordinatesTransformation.service'
 import { hot } from 'jasmine-marbles'
-import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from './viewerState.base'
 import { AngularMaterialModule } from '../sharedModules/angularMaterial.module'
 import { HttpClientModule } from '@angular/common/http'
 import { WidgetModule } from 'src/widget'
 import { PluginModule } from 'src/atlasViewer/pluginUnit/plugin.module'
+import { viewerStateNavigationStateSelector, viewerStateNewViewer, viewerStateSelectTemplateWithName } from 'src/services/state/viewerState.store.helper'
 
 const bigbrainJson = require('!json-loader!src/res/ext/bigbrain.json')
+const bigBrainNehubaConfig = require('!json-loader!src/res/ext/bigbrainNehubaConfig.json')
 const colinJson = require('!json-loader!src/res/ext/colin.json')
 const colinJsonNehubaConfig = require('!json-loader!src/res/ext/colinNehubaConfig.json')
 const reconstitutedColin = JSON.parse(JSON.stringify(
@@ -22,6 +23,12 @@ const reconstitutedColin = JSON.parse(JSON.stringify(
     nehubaConfig: colinJsonNehubaConfig
   }
 ))
+const reconstitutedBigBrain = JSON.parse(JSON.stringify(
+  {
+    ...bigbrainJson,
+    nehubaConfig: bigBrainNehubaConfig
+  }
+))
 let returnPosition = null
 @Injectable()
 class MockCoordXformService{
@@ -34,7 +41,7 @@ class MockCoordXformService{
 
 const initialState = JSON.parse(JSON.stringify( defaultRootState ))
 initialState.viewerState.fetchedTemplates = [
-  bigbrainJson,
+  reconstitutedBigBrain,
   reconstitutedColin
 ]
 initialState.viewerState.templateSelected = initialState.viewerState.fetchedTemplates[0]
@@ -47,8 +54,8 @@ const currentNavigation = {
 }
 initialState.viewerState.navigation = currentNavigation
 
-describe('viewerState.useEffect.ts', () => {
-  describe('ViewerStateControllerUseEffect', () => {
+describe('> viewerState.useEffect.ts', () => {
+  describe('> ViewerStateControllerUseEffect', () => {
     let actions$: Observable<any>
     let spy: any
     beforeEach(async(() => {
@@ -59,10 +66,7 @@ describe('viewerState.useEffect.ts', () => {
       actions$ = hot(
         'a',
         {
-          a: { 
-            type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.SELECT_TEMPLATE_WITH_NAME,
-            payload: reconstitutedColin
-          }
+          a: viewerStateSelectTemplateWithName({ payload: reconstitutedColin })
         }
       )
 
@@ -85,27 +89,94 @@ describe('viewerState.useEffect.ts', () => {
       }).compileComponents()
     }))
 
-    describe('selectTemplate$', () => {
+    describe('> selectTemplate$', () => {
+      describe('> when transiting from template A to template B', () => {
+        describe('> if the current navigation is correctly formed', () => {
+          it('> uses current navigation param', () => {
 
-      it('if coordXform returns error', () => {
-        const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
-        expect(
-          viewerStateCtrlEffect.selectTemplate$
-        ).toBeObservable(
-          hot(
-            'a',
-            {
-              a: {
-                type: NEWVIEWER,
-                selectTemplate: reconstitutedColin,
-                selectParcellation: reconstitutedColin.parcellations[0]
-              }
-            }
-          )
-        )
+            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
+            expect(
+              viewerStateCtrlEffect.selectTemplate$
+            ).toBeObservable(
+              hot(
+                'a',
+                {
+                  a: viewerStateNewViewer({
+                      selectTemplate: reconstitutedColin,
+                      selectParcellation: reconstitutedColin.parcellations[0],
+                    })
+                }
+              )
+            )
+            expect(spy).toHaveBeenCalledWith(
+              reconstitutedBigBrain.name,
+              reconstitutedColin.name,
+              initialState.viewerState.navigation.position
+            )
+          })
+        })
+
+        describe('> if current navigation is malformed', () => {
+          it('> if current navigation is undefined, use nehubaConfig of last template', () => {
+
+            const mockStore = TestBed.inject(MockStore)
+            mockStore.overrideSelector(viewerStateNavigationStateSelector, null)
+            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
+
+            expect(
+              viewerStateCtrlEffect.selectTemplate$
+            ).toBeObservable(
+              hot(
+                'a',
+                {
+                  a: viewerStateNewViewer({
+                      selectTemplate: reconstitutedColin,
+                      selectParcellation: reconstitutedColin.parcellations[0],
+                    })
+                }
+              )
+            )
+            const { position } = cvtNehubaConfigToNavigationObj(reconstitutedBigBrain.nehubaConfig.dataset.initialNgState)
+
+            expect(spy).toHaveBeenCalledWith(
+              reconstitutedBigBrain.name,
+              reconstitutedColin.name,
+              position
+            )
+          })
+  
+          it('> if current navigation is empty object, use nehubaConfig of last template', () => {
+
+            const mockStore = TestBed.inject(MockStore)
+            mockStore.overrideSelector(viewerStateNavigationStateSelector, {})
+            const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
+
+            expect(
+              viewerStateCtrlEffect.selectTemplate$
+            ).toBeObservable(
+              hot(
+                'a',
+                {
+                  a: viewerStateNewViewer({
+                      selectTemplate: reconstitutedColin,
+                      selectParcellation: reconstitutedColin.parcellations[0],
+                    })
+                }
+              )
+            )
+            const { position } = cvtNehubaConfigToNavigationObj(reconstitutedBigBrain.nehubaConfig.dataset.initialNgState)
+
+            expect(spy).toHaveBeenCalledWith(
+              reconstitutedBigBrain.name,
+              reconstitutedColin.name,
+              position
+            )
+          })
+        })
+  
       })
 
-      it('calls with correct param', () => {
+      it('> if coordXform returns error', () => {
         const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
         expect(
           viewerStateCtrlEffect.selectTemplate$
@@ -113,26 +184,21 @@ describe('viewerState.useEffect.ts', () => {
           hot(
             'a',
             {
-              a: {
-                type: NEWVIEWER,
-                selectTemplate: reconstitutedColin,
-                selectParcellation: reconstitutedColin.parcellations[0]
-              }
+              a: viewerStateNewViewer({
+                  selectTemplate: reconstitutedColin,
+                  selectParcellation: reconstitutedColin.parcellations[0],
+                })
             }
           )
         )
-        expect(spy).toHaveBeenCalledWith(
-          bigbrainJson.name,
-          reconstitutedColin.name,
-          initialState.viewerState.navigation.position
-        )
       })
 
-      it('if coordXform returns complete', () => {
+      it('> if coordXform complete', () => {
         returnPosition = [ 1.11e6, 2.22e6, 3.33e6 ]
 
         const viewerStateCtrlEffect = TestBed.inject(ViewerStateControllerUseEffect)
         const updatedColin = JSON.parse( JSON.stringify( reconstitutedColin ) )
+        const initialNgState = updatedColin.nehubaConfig.dataset.initialNgState
         const updatedColinNavigation = updatedColin.nehubaConfig.dataset.initialNgState.navigation
 
         const { zoom, orientation, perspectiveOrientation, position, perspectiveZoom } = currentNavigation
@@ -142,6 +208,8 @@ describe('viewerState.useEffect.ts', () => {
         }
         updatedColinNavigation.zoomFactor = zoom
         updatedColinNavigation.pose.orientation = orientation
+        initialNgState.perspectiveOrientation = perspectiveOrientation
+        initialNgState.perspectiveZoom = perspectiveZoom
         
         expect(
           viewerStateCtrlEffect.selectTemplate$
@@ -149,15 +217,136 @@ describe('viewerState.useEffect.ts', () => {
           hot(
             'a',
             {
-              a: {
-                type: NEWVIEWER,
-                selectTemplate: updatedColin,
-                selectParcellation: updatedColin.parcellations[0]
-              }
+              a: viewerStateNewViewer({
+                  selectTemplate: updatedColin,
+                  selectParcellation: updatedColin.parcellations[0],
+                })
             }
           )
         )
       })
+
+    })
+  })
+
+  describe('> cvtNehubaConfigToNavigationObj', () => {
+    describe('> returns default obj when input is malformed', () => {
+      it('> if no arg is provided', () => {
+
+        const obj = cvtNehubaConfigToNavigationObj()
+        expect(obj).toEqual({
+          orientation: [0, 0, 0, 1],
+          perspectiveOrientation: [0 , 0, 0, 1],
+          perspectiveZoom: 1e6,
+          zoom: 1e6,
+          position: [0, 0, 0],
+          positionReal: true
+        })
+      })
+      it('> if null or undefined is provided', () => {
+
+        const obj = cvtNehubaConfigToNavigationObj(null)
+        expect(obj).toEqual(defaultNavigationObject)
+
+        const obj2 = cvtNehubaConfigToNavigationObj(undefined)
+        expect(obj2).toEqual(defaultNavigationObject)
+      })
+      it('> if malformed', () => {
+        
+        const obj = cvtNehubaConfigToNavigationObj(reconstitutedBigBrain)
+        expect(obj).toEqual(defaultNavigationObject)
+
+        const obj2 = cvtNehubaConfigToNavigationObj({})
+        expect(obj2).toEqual(defaultNavigationObject)
+      })
+    })
+    it('> converts nehubaConfig object to navigation object', () => {
+
+      const obj = cvtNehubaConfigToNavigationObj(reconstitutedBigBrain.nehubaConfig.dataset.initialNgState)
+      expect(obj).toEqual({
+        orientation: [0, 0, 0, 1],
+        perspectiveOrientation: [
+          0.3140767216682434,
+          -0.7418519854545593,
+          0.4988985061645508,
+          -0.3195493221282959
+        ],
+        perspectiveZoom: 1922235.5293810747,
+        zoom: 350000,
+        position: [ -463219.89446663484, 325772.3617553711, 601535.3736234978 ],
+        positionReal: true
+      })
+    })
+  })
+  describe('> cvtNavigationObjToNehubaConfig', () => {
+    const validNehubaConfigObj = reconstitutedBigBrain.nehubaConfig.dataset.initialNgState
+    const validNavigationObj = currentNavigation
+    describe('> if inputs are malformed', () => {
+      describe('> if navigation object is malformed, uses navigation default object', () => {
+        it('> if navigation object is null', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(null, validNehubaConfigObj)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, validNehubaConfigObj)
+          expect(v1).toEqual(v2)
+        })
+        it('> if navigation object is undefined', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(undefined, validNehubaConfigObj)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, validNehubaConfigObj)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if navigation object is otherwise malformed', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(reconstitutedBigBrain, validNehubaConfigObj)
+          const v2 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, validNehubaConfigObj)
+          expect(v1).toEqual(v2)
+
+          const v3 = cvtNavigationObjToNehubaConfig({}, validNehubaConfigObj)
+          const v4 = cvtNavigationObjToNehubaConfig(defaultNavigationObject, validNehubaConfigObj)
+          expect(v3).toEqual(v4)
+        })
+      })
+
+      describe('> if nehubaConfig object is malformed, use default nehubaConfig obj', () => {
+        it('> if nehubaConfig is null', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, null)
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if nehubaConfig is undefined', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, undefined)
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+        })
+
+        it('> if nehubaConfig is otherwise malformed', () => {
+          const v1 = cvtNavigationObjToNehubaConfig(validNavigationObj, {})
+          const v2 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v1).toEqual(v2)
+
+          const v3 = cvtNavigationObjToNehubaConfig(validNavigationObj, reconstitutedBigBrain)
+          const v4 = cvtNavigationObjToNehubaConfig(validNavigationObj, defaultNehubaConfigObject)
+          expect(v3).toEqual(v4)
+        })
+      })
+    })
+    it('> converts navigation object and reference nehuba config object to navigation object', () => {
+      const convertedVal = cvtNavigationObjToNehubaConfig(validNavigationObj, validNehubaConfigObj)
+      const { perspectiveOrientation, orientation, zoom, perspectiveZoom, position } = validNavigationObj
+      
+      expect(convertedVal).toEqual({
+        navigation: {
+          pose: {
+            position: {
+              voxelSize: validNehubaConfigObj.navigation.pose.position.voxelSize,
+              voxelCoordinates: [0, 1, 2].map(idx => position[idx] / validNehubaConfigObj.navigation.pose.position.voxelSize[idx])
+            },
+            orientation
+          },
+          zoomFactor: zoom
+        },
+        perspectiveOrientation: perspectiveOrientation,
+        perspectiveZoom: perspectiveZoom
+      })
     })
   })
-})
\ No newline at end of file
+})
diff --git a/src/ui/viewerStateController/viewerState.useEffect.ts b/src/ui/viewerStateController/viewerState.useEffect.ts
index 8edba98ef705137f2a8256a9725e06e5d95e20a9..292d47435e236ea0c07a8f2c8bea00f7b108cf26 100644
--- a/src/ui/viewerStateController/viewerState.useEffect.ts
+++ b/src/ui/viewerStateController/viewerState.useEffect.ts
@@ -2,15 +2,96 @@ import { Injectable, OnDestroy } from "@angular/core";
 import { Actions, Effect, ofType } from "@ngrx/effects";
 import { Action, select, Store } from "@ngrx/store";
 import { Observable, Subscription, of, merge } from "rxjs";
-import { distinctUntilChanged, filter, map, shareReplay, withLatestFrom, switchMap, mapTo } from "rxjs/operators";
-import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
+import { distinctUntilChanged, filter, map, shareReplay, withLatestFrom, switchMap, mapTo, startWith } from "rxjs/operators";
 import { CHANGE_NAVIGATION, FETCHED_TEMPLATE, IavRootStoreInterface, NEWVIEWER, SELECT_PARCELLATION, SELECT_REGIONS, generalActionError } from "src/services/stateStore.service";
 import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "./viewerState.base";
 import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
 import { CLEAR_STANDALONE_VOLUMES } from "src/services/state/viewerState.store";
-import { viewerStateToggleRegionSelect, viewerStateHelperSelectParcellationWithId, viewerStateSelectTemplateWithId, viewerStateNavigateToRegion, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState.store.helper";
+import { viewerStateToggleRegionSelect, viewerStateHelperSelectParcellationWithId, viewerStateSelectTemplateWithId, viewerStateNavigateToRegion, viewerStateSelectedTemplateSelector, viewerStateFetchedTemplatesSelector, viewerStateNewViewer, viewerStateSelectedParcellationSelector, viewerStateNavigationStateSelector, viewerStateSelectTemplateWithName } from "src/services/state/viewerState.store.helper";
 import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState/selectors";
 import { ngViewerActionClearView } from "src/services/state/ngViewerState/actions";
+import { PureContantService } from "src/util";
+
+const defaultPerspectiveZoom = 1e6
+const defaultZoom = 1e6
+
+export const defaultNavigationObject = {
+  orientation: [0, 0, 0, 1],
+  perspectiveOrientation: [0 , 0, 0, 1],
+  perspectiveZoom: defaultPerspectiveZoom,
+  zoom: defaultZoom,
+  position: [0, 0, 0],
+  positionReal: true
+}
+
+export const defaultNehubaConfigObject = {
+  perspectiveOrientation: [0, 0, 0, 1],
+  perspectiveZoom: 1e6,
+  navigation: {
+    pose: {
+      position: {
+        voxelCoordinates: [0, 0, 0],
+        voxelSize: [1,1,1]
+      },
+      orientation: [0, 0, 0, 1],
+    },
+    zoomFactor: defaultZoom
+  }
+}
+
+export function cvtNehubaConfigToNavigationObj(nehubaConfig?){
+  const { navigation, perspectiveOrientation = [0, 0, 0, 1], perspectiveZoom = 1e6 } = nehubaConfig || {}
+  const { pose, zoomFactor = 1e6 } = navigation || {}
+  const { position, orientation = [0, 0, 0, 1] } = pose || {}
+  const { voxelSize = [1, 1, 1], voxelCoordinates = [0, 0, 0] } = position || {}
+
+  return {
+    orientation,
+    perspectiveOrientation: perspectiveOrientation,
+    perspectiveZoom: perspectiveZoom,
+    zoom: zoomFactor,
+    position: [0, 1, 2].map(idx => voxelSize[idx] * voxelCoordinates[idx]),
+    positionReal: true
+  }
+}
+
+export function cvtNavigationObjToNehubaConfig(navigationObj, nehubaConfigObj){
+  const {
+    orientation = [0, 0, 0, 1],
+    perspectiveOrientation = [0, 0, 0, 1],
+    perspectiveZoom = 1e6,
+    zoom = 1e6,
+    position = [0, 0, 0],
+    positionReal = true,
+  } = navigationObj || {}
+
+  const voxelSize = (() => {
+    const {
+      navigation = {}
+    } = nehubaConfigObj || {}
+    const { pose = {}, zoomFactor = 1e6 } = navigation
+    const { position = {}, orientation = [0, 0, 0, 1] } = pose
+    const { voxelSize = [1, 1, 1], voxelCoordinates = [0, 0, 0] } = position
+    return voxelSize
+  })()
+
+  return {
+    perspectiveOrientation,
+    perspectiveZoom,
+    navigation: {
+      pose: {
+        position: {
+          voxelCoordinates: positionReal
+            ? [0, 1, 2].map(idx => position[idx] / voxelSize[idx])
+            : position,
+          voxelSize
+        },
+        orientation,
+      },
+      zoomFactor: zoom
+    }
+  }
+}
 
 @Injectable({
   providedIn: 'root',
@@ -23,7 +104,7 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
   private selectedRegions$: Observable<any[]>
 
   @Effect()
-  public init$ = this.constantSerivce.initFetchTemplate$.pipe(
+  public init$ = this.pureService.initFetchTemplate$.pipe(
     map(fetchedTemplate => {
       return {
         type: FETCHED_TEMPLATE,
@@ -35,8 +116,151 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
   @Effect()
   public selectParcellation$: Observable<any>
 
+  private selectTemplateIntent$: Observable<any> = merge(
+    this.actions$.pipe(
+      ofType(viewerStateSelectTemplateWithId.type),
+      map(({ payload, config }) => {
+        return {
+          templateId: payload['@id'],
+          parcellationId: config && config['selectParcellation'] && config['selectParcellation']['@id']
+        }
+      })
+    ),
+    this.actions$.pipe(
+      ofType(viewerStateSelectTemplateWithName),
+      withLatestFrom(this.store$.pipe(
+        select(viewerStateFetchedTemplatesSelector)
+      )),
+      map(([ action, fetchedTemplates ]) => {
+        const templateName = (action as any).payload.name
+        const foundTemplate = fetchedTemplates.find(t => t.name === templateName)
+        return foundTemplate && foundTemplate['@id']
+      }),
+      filter(v => !!v),
+      map(templateId => {
+        return { templateId, parcellationId: null }
+      })
+    )
+  )
+
   @Effect()
-  public selectTemplate$: Observable<any>
+  public selectTemplate$: Observable<any> = this.selectTemplateIntent$.pipe(
+    withLatestFrom(
+      this.store$.pipe(
+        select(viewerStateFetchedTemplatesSelector)
+      ),
+      this.store$.pipe(
+        select(viewerStateSelectedParcellationSelector)
+      )
+    ),
+    map(([ { templateId, parcellationId }, fetchedTemplates, parcellationSelected ]) => {
+      /**
+       * find the correct template & parcellation from their IDs
+       */
+
+      /**
+       * for template, just look for the new id in fetched templates
+       */
+      const newTemplateTobeSelected = fetchedTemplates.find(t => t['@id'] === templateId)
+      if (!newTemplateTobeSelected) {
+        return {
+          selectTemplate: null,
+          selectParcellation: null,
+          errorMessage: `Selected templateId ${templateId} not found.`
+        }
+      }
+
+      /**
+       * for parcellation,
+       * if new parc id is defined, try to find the corresponding parcellation in the new template
+       * if above fails, try to find the corresponding parcellation of the currently selected parcellation
+       * if the above fails, select the first parcellation in the new template
+       */
+      const selectParcellationWithTemplate = (parcellationId && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === parcellationId))
+        || (parcellationSelected && parcellationSelected['@id'] && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === parcellationSelected['@id']))
+        || newTemplateTobeSelected.parcellations[0]
+
+      return {
+        selectTemplate: newTemplateTobeSelected,
+        selectParcellation: selectParcellationWithTemplate
+      }
+    }),
+    withLatestFrom(
+      this.store$.pipe(
+        select(viewerStateSelectedTemplateSelector),
+        startWith(null as any),
+      ),
+      this.store$.pipe(
+        select(viewerStateNavigationStateSelector),
+        startWith(null as any),
+      )
+    ),
+    switchMap(([{ selectTemplate, selectParcellation, errorMessage }, lastSelectedTemplate, navigation]) => {
+      /**
+       * if selectTemplate is undefined (cannot find template with id)
+       */
+      if (errorMessage) {
+        return of(generalActionError({
+          message: errorMessage || 'Switching template error.',
+        }))
+      }
+      /**
+       * if there were no template selected last
+       * simply return selectTemplate object
+       */
+      if (!lastSelectedTemplate) {
+        return of(viewerStateNewViewer({
+          selectParcellation,
+          selectTemplate,
+        }))
+      }
+
+      /**
+       * if there were template selected last, extract navigation info
+       */
+      const previousNavigation = (navigation && Object.keys(navigation).length > 0 && navigation) || cvtNehubaConfigToNavigationObj(lastSelectedTemplate.nehubaConfig?.dataset?.initialNgState)
+      return this.coordinatesTransformation.getPointCoordinatesForTemplate(lastSelectedTemplate.name, selectTemplate.name, previousNavigation.position).pipe(
+        map(({ status, result }) => {
+
+          /**
+           * if getPointCoordinatesForTemplate returns error, simply load the temp/parc
+           */
+          if (status === 'error') {
+            return viewerStateNewViewer({
+              selectParcellation,
+              selectTemplate,
+            })
+          }
+
+          /**
+           * otherwise, copy the nav state to templateSelected
+           * deepclone of json object is required, or it will mutate the fetchedTemplate
+           * setting navigation sometimes creates a race con, as creating nehubaViewer is not sync
+           */
+          const deepCopiedState = JSON.parse(JSON.stringify(selectTemplate))
+          const initialNgState = deepCopiedState.nehubaConfig.dataset.initialNgState
+
+          const newInitialNgState = cvtNavigationObjToNehubaConfig({
+            ...previousNavigation,
+            position: result
+          }, initialNgState)
+
+          /**
+           * mutation of initialNgState is expected here
+           */
+          deepCopiedState.nehubaConfig.dataset.initialNgState = {
+            ...initialNgState,
+            ...newInitialNgState
+          }
+
+          return viewerStateNewViewer({
+            selectTemplate: deepCopiedState,
+            selectParcellation,
+          })
+        })
+      )
+    })
+  )
 
   @Effect()
   public toggleRegionSelection$: Observable<any>
@@ -67,7 +291,7 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
   constructor(
     private actions$: Actions,
     private store$: Store<IavRootStoreInterface>,
-    private constantSerivce: AtlasViewerConstantsServices,
+    private pureService: PureContantService,
     private coordinatesTransformation: TemplateCoordinatesTransformation
   ) {
     const viewerState$ = this.store$.pipe(
@@ -135,121 +359,6 @@ export class ViewerStateControllerUseEffect implements OnDestroy {
       })
     )
 
-    /**
-     * merge all sources into single stream consisting of template id's
-     */
-    this.selectTemplate$ = merge(
-      this.actions$.pipe(
-        ofType(viewerStateSelectTemplateWithId.type),
-        map(({ payload, config }) => {
-          return {
-            templateId: payload['@id'],
-            parcellationId: config && config['selectParcellation'] && config['selectParcellation']['@id']
-          }
-        })
-      ),
-      this.actions$.pipe(
-        ofType(VIEWERSTATE_CONTROLLER_ACTION_TYPES.SELECT_TEMPLATE_WITH_NAME),
-        withLatestFrom(viewerState$.pipe(
-          select('fetchedTemplates')
-        )),
-        map(([ action, fetchedTemplates ]) => {
-          const templateName = (action as any).payload.name
-          const foundTemplate = fetchedTemplates.find(t => t.name === templateName)
-          return foundTemplate && foundTemplate['@id']
-        }),
-        filter(v => !!v),
-        map(templateId => {
-          return { templateId, parcellationId: null }
-        })
-      )
-    ).pipe(
-
-      withLatestFrom(
-        viewerState$
-      ),
-      switchMap(([{ templateId: newTemplateId, parcellationId: newParcellationId }, { templateSelected, fetchedTemplates, navigation, parcellationSelected }]) => {
-        if (!templateSelected) {
-          return of({
-            newTemplateId,
-            templateSelected: templateSelected,
-            fetchedTemplates,
-            translatedCoordinate: null,
-            navigation,
-            newParcellationId,
-            parcellationSelected
-          })
-        }
-        const position = (navigation && navigation.position) || [0, 0, 0]
-        if (newTemplateId === templateSelected['@id']) return of(null)
-
-        const newTemplateName = fetchedTemplates.find(t => t['@id'] === newTemplateId).name
-
-        return this.coordinatesTransformation.getPointCoordinatesForTemplate(templateSelected.name, newTemplateName, position).pipe(
-          map(({ status, statusText, result }) => {
-            if (status === 'error') {
-              return {
-                newTemplateId,
-                templateSelected: templateSelected,
-                fetchedTemplates,
-                translatedCoordinate: null,
-                navigation,
-                newParcellationId,
-                parcellationSelected
-              }
-            }
-            return {
-              newTemplateId,
-              templateSelected: templateSelected,
-              fetchedTemplates,
-              translatedCoordinate: result,
-              navigation,
-              newParcellationId,
-              parcellationSelected
-            }
-          })
-        )
-      }),
-      filter(v => !!v),
-      map(({ newTemplateId, templateSelected, newParcellationId, fetchedTemplates, translatedCoordinate, navigation, parcellationSelected }) => {
-        const newTemplateTobeSelected = fetchedTemplates.find(t => t['@id'] === newTemplateId)
-        if (!newTemplateTobeSelected) {
-          return generalActionError({
-            message: 'Selected template not found.'
-          })
-        }
-
-        const selectParcellationWithTemplate = (newParcellationId && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === newParcellationId))
-          || (parcellationSelected && parcellationSelected['@id'] && newTemplateTobeSelected['parcellations'].find(p => p['@id'] === parcellationSelected['@id']))
-          || newTemplateTobeSelected.parcellations[0]
-
-        if (!translatedCoordinate) {
-          return {
-            type: NEWVIEWER,
-            selectTemplate: newTemplateTobeSelected,
-            selectParcellation: selectParcellationWithTemplate,
-          }
-        }
-        const deepCopiedState = JSON.parse(JSON.stringify(newTemplateTobeSelected))
-        const initNavigation = deepCopiedState.nehubaConfig.dataset.initialNgState.navigation
-
-        const { zoom = null, orientation = null } = navigation || {}
-        if (zoom) initNavigation.zoomFactor = zoom
-        if (orientation) initNavigation.pose.orientation = orientation
-
-        for (const idx of [0, 1, 2]) {
-          initNavigation.pose.position.voxelCoordinates[idx] = translatedCoordinate[idx] / initNavigation.pose.position.voxelSize[idx]
-        }
-
-        return {
-          type: NEWVIEWER,
-          selectTemplate: deepCopiedState,
-          selectParcellation: selectParcellationWithTemplate,
-        }
-      }),
-    )
-
-
     this.navigateToRegion$ = this.actions$.pipe(
       ofType(viewerStateNavigateToRegion),
       map(action => {
diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts
index 5cdd0b0cffa480e53e6cd811b9a6601493c8e6a1..2f9e6bafd5d980217c4daaeb0893766966d74996 100644
--- a/src/util/pureConstant.service.ts
+++ b/src/util/pureConstant.service.ts
@@ -1,11 +1,15 @@
 import { Injectable, OnDestroy } from "@angular/core";
 import { Store, createSelector, select } from "@ngrx/store";
-import { Observable, merge, Subscription, of } from "rxjs";
+import { Observable, merge, Subscription, of, throwError, forkJoin, fromEvent } from "rxjs";
 import { VIEWER_CONFIG_FEATURE_KEY, IViewerConfigState } from "src/services/state/viewerConfig.store.helper";
-import { shareReplay, tap, scan, catchError, filter, mergeMap, switchMapTo, switchMap } from "rxjs/operators";
+import { shareReplay, tap, scan, catchError, filter, switchMap, map, take } from "rxjs/operators";
 import { HttpClient } from "@angular/common/http";
 import { BACKENDURL } from './constants'
 import { viewerStateSetFetchedAtlases } from "src/services/state/viewerState.store.helper";
+import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
+import { LoggingService } from "src/logging";
+
+const getUniqueId = () => Math.round(Math.random() * 1e16).toString(16)
 
 @Injectable({
   providedIn: 'root'
@@ -24,9 +28,85 @@ export class PureContantService implements OnDestroy{
     (state: IViewerConfigState) => state.useMobileUI
   )
 
+  public backendUrl = (BACKEND_URL && `${BACKEND_URL}/`.replace(/\/\/$/, '/')) || `${window.location.origin}${window.location.pathname}`
+
+  private workerUpdateParcellation$ = fromEvent(this.workerService.worker, 'message').pipe(
+    filter((message: MessageEvent) => message && message.data && message.data.type === 'UPDATE_PARCELLATION_REGIONS'),
+    map(({ data }) => data)
+  )
+
+  private fetchTemplate = (templateUrl) => this.http.get(`${this.backendUrl}${templateUrl}`, { responseType: 'json' }).pipe(
+    switchMap((template: any) => {
+      if (template.nehubaConfig) { return of(template) }
+      if (template.nehubaConfigURL) { return this.http.get(`${this.backendUrl}${template.nehubaConfigURL}`, { responseType: 'json' }).pipe(
+        map(nehubaConfig => {
+          return {
+            ...template,
+            nehubaConfig,
+          }
+        }),
+      )
+      }
+      throwError('neither nehubaConfig nor nehubaConfigURL defined')
+    }),
+  )
+
+  private processTemplate = template => forkJoin(
+    template.parcellations.map(parcellation => {
+
+      const id = getUniqueId()
+
+      this.workerService.worker.postMessage({
+        type: 'PROPAGATE_PARC_REGION_ATTR',
+        parcellation,
+        inheritAttrsOpts: {
+          ngId: (parcellation as any ).ngId,
+          relatedAreas: [],
+          fullId: null
+        },
+        id
+      })
+
+      return this.workerUpdateParcellation$.pipe(
+        filter(({ id: returnedId }) => id === returnedId),
+        take(1),
+        map(({ parcellation }) => parcellation)
+      )
+    })
+  )
+
+  public getTemplateEndpoint$ = this.http.get<any[]>(`${this.backendUrl}templates`, { responseType: 'json' }).pipe(
+    catchError(() => {
+      this.log.warn(`fetching root /tempaltes error`)
+      return of([])
+    }),
+    shareReplay(),
+  )
+
+  public initFetchTemplate$ = this.getTemplateEndpoint$.pipe(
+    switchMap((templates: string[]) => merge(
+      ...templates.map(templateName => this.fetchTemplate(templateName).pipe(
+        switchMap(template => this.processTemplate(template).pipe(
+          map(parcellations => {
+            return {
+              ...template,
+              parcellations
+            }
+          })
+        ))
+      )),
+    )),
+    catchError((err) => {
+      this.log.warn(`fetching templates error`, err)
+      return of(null)
+    }),
+  )
+
   constructor(
     private store: Store<any>,
     private http: HttpClient,
+    private log: LoggingService,
+    private workerService: AtlasWorkerService,
   ){
     this.darktheme$ = this.store.pipe(
       select(state => state?.viewerState?.templateSelected?.useTheme === 'dark')