diff --git a/apps/commons/src/pages/imageviewer/imageViewer.css b/apps/commons/src/pages/imageviewer/imageViewer.css
new file mode 100644
index 0000000000000000000000000000000000000000..745003246b0cebcc716dc0a95f6bba841b3a5d00
--- /dev/null
+++ b/apps/commons/src/pages/imageviewer/imageViewer.css
@@ -0,0 +1,63 @@
+.imageViewer {
+    display: table;
+    height: 100%;
+    width: 100%;
+}
+
+.imageViewer .toolbar {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 32px;
+    padding: 8px;
+    margin-top: 4px;
+}
+
+.imageViewer .image {
+    display: table-row;
+    height: 100%;
+}
+
+.imageViewer .toolbar .navigation {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+}
+
+.imageViewer .toolbar .zoom {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+}
+
+.imageViewer .lw-button {
+    display: flex !important;
+    align-items: center;
+    justify-content: center;
+    width: 24px;
+    height: 24px;
+    border-radius: 3px;
+}
+
+.imageViewer .lw-button:hover {
+    cursor: pointer;
+    background-color: rgba(0, 0, 0, .1);
+    /* border: 1px solid #aaa; */
+}
+
+.imageViewer .pageInfo {
+    /* display: block;
+    position: relative;
+    float: right;
+    margin: 5px 3px; */
+}
+
+.imageViewer input.currPage {
+    height: 20px;
+    width: 20px;
+    text-align: right;
+}
+
+.imageViewer .openseadragon-message {
+    white-space: pre;
+}
\ No newline at end of file
diff --git a/apps/commons/src/pages/imageviewer/index.tsx b/apps/commons/src/pages/imageviewer/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..47313a8443ad828a0eb1fa9d9d14cde6fc9c38b8
--- /dev/null
+++ b/apps/commons/src/pages/imageviewer/index.tsx
@@ -0,0 +1,95 @@
+import { Box, Link, Stack, Typography } from '@mui/material';
+import { Logo } from '@src/components';
+import { Page } from '@src/layouts';
+import { Trans, useTranslation } from 'react-i18next';
+import { Link as RouterLink } from 'react-router';
+import { BroadcastChannel } from 'broadcast-channel';
+import { useEffect, useState } from 'react';
+import OpenSeaDragon from 'openseadragon';
+import './imageViewer.css'
+
+export const ImageViewerPage = () => {
+  const { t } = useTranslation();
+  const channel = new BroadcastChannel('imageViewer-channel');
+  const [images, setImages] = useState("")
+  const id: string = "LEAF-Wwriter-SepImageViewer"
+  //var viewer: any;
+
+  useEffect(() => {
+    const handleMessage = (event) => {
+      console.log(event)
+      if (event.tileSources) {
+        setImages(event.tileSources);
+      }
+    };
+
+    channel.onmessage = handleMessage;
+
+    // Clean up the channel when the component unmounts
+    return () => {
+        channel.close();
+    };
+  }, [channel]);
+
+  useEffect(() => {
+    channel.postMessage({imageViewerWindowReady: true})
+    console.log("HIU")
+  }, [])
+
+  useEffect(() => {
+    console.log(images)
+  }, [images])
+
+  useEffect(() => {
+
+    let viewer = OpenSeaDragon({
+      id: 'seadragon-viewer',
+      sequenceMode: true,
+      autoHideControls: false,
+      showFullPageControl: false,
+      previousButton: `${id}_prev`,
+      nextButton: `${id}_next`,
+      zoomInButton: `${id}_zoomIn`,
+      zoomOutButton: `${id}_zoomOut`,
+      homeButton: `${id}_home`,
+    });
+    console.log(images)
+    viewer.open(images)
+
+    // Cleanup (equal to componentWillUnmount)
+    return () => {
+      viewer.destroy();
+      viewer = null;
+    };
+  }, [images]);
+
+  return (
+    <div id={id} className="imageViewer">
+        <div className="toolbar">
+          <div className="navigation">
+            <span id={id + "_prev"} className="lw-button">
+              <i className="fas fa-arrow-left"></i>
+            </span>
+            <span id={id + "_next"} className="lw-button">
+              <i className="fas fa-arrow-right"></i>
+            </span>
+            <span className="pageInfo">
+              <input type="text" className="currPage" /> / <span className="totalPages"/>
+            </span>
+          </div>
+          <div className="zoom">
+            <span id={id + "_zoomIn"} className="lw-button">
+              <i className="fas fa-search-plus"></i>
+            </span>
+            <span id={id + "_zoomOut"} className="lw-button">
+              <i className="fas fa-search-minus"></i>
+            </span>
+            <span id={id + "_home"} className="lw-button">
+              <i className="fas fa-compress"></i>
+            </span>
+          </div>
+        </div>
+        <div id="seadragon-viewer" className="seadragon-viewer" />
+      </div>
+  );
+};
diff --git a/apps/commons/src/pages/index.ts b/apps/commons/src/pages/index.ts
index 56bd97c36732c3704840685f1f7eb165ce72bd78..9d36d32d32590a011b2ee59a9a66057f9916388f 100644
--- a/apps/commons/src/pages/index.ts
+++ b/apps/commons/src/pages/index.ts
@@ -2,3 +2,4 @@ export * from './LinkAccounts';
 export * from './edit';
 export * from './error/NotFoundView';
 export * from './home';
+export * from './imageviewer';
diff --git a/apps/commons/src/routes.tsx b/apps/commons/src/routes.tsx
index 071dd8a80c619b80185dfc70ca2173565dfaa06c..550fef7391b61ff3dbd72e96c0418c005f390630 100644
--- a/apps/commons/src/routes.tsx
+++ b/apps/commons/src/routes.tsx
@@ -1,5 +1,5 @@
 import { BasicLayout } from './layouts';
-import { EditPage, HomePage, LinkAccountsPage, NotFoundPage } from './pages';
+import { EditPage, HomePage, LinkAccountsPage, NotFoundPage, ImageViewerPage } from './pages';
 
 export const routes = [
   {
@@ -10,6 +10,7 @@ export const routes = [
       { path: '/link-accounts', element: <LinkAccountsPage /> },
       { path: '/edit', element: <EditPage /> },
       { path: '/view', element: <EditPage /> },
+      { path: '/imageviewer', element: <ImageViewerPage /> },
       { index: true, element: <HomePage /> },
     ],
   },
diff --git a/packages/cwrc-leafwriter/src/components/editorToolbar/index.tsx b/packages/cwrc-leafwriter/src/components/editorToolbar/index.tsx
index 9eee8a96d27ce8c4f3fecfa0aa5230943d09d37d..c133ed4b60907ebee9c72752639520fe11a14193 100644
--- a/packages/cwrc-leafwriter/src/components/editorToolbar/index.tsx
+++ b/packages/cwrc-leafwriter/src/components/editorToolbar/index.tsx
@@ -8,6 +8,9 @@ import { Button } from './Button';
 import { IconButton } from './IconButton';
 import { Toggle } from './Toggle';
 import { Trans, useTranslation } from 'react-i18next';
+//import PortalComponent from './PortalComponent';
+import { BroadcastChannel } from 'broadcast-channel';
+import { useEffect, useState } from 'react';
 
 type ItemType = 'button' | 'divider' | 'iconButton' | 'toggle';
 type ItemGroup = 'action' | 'ui' | 'panel' | 'general';
@@ -42,6 +45,28 @@ export const EditorToolbar = () => {
 
   const container = useRef<HTMLDivElement>(null);
 
+  /*
+  const [showPortal, setShowPortal] = useState(false);
+
+  const channel = new BroadcastChannel('imageViewer-channel');
+  const [message, setMessage] = useState("")
+
+  useEffect(() => {
+    const handleMessage = (event) => {
+      console.log(event)
+      if (event.imageViewerWindowReady && event.imageViewerWindowReady == true) {
+        channel.postMessage({dataIn: "Hi, I am Broadcast!"})
+      }
+    };
+
+    channel.onmessage = handleMessage;
+
+    // Clean up the channel when the component unmounts
+    return () => {
+        channel.close();
+    };
+}, [channel]);*/
+
   const isSupported = useCallback(
     (name: EntityType) => window.writer.schemaManager.mapper.getEntitiesMapping().has(name),
     [schemaId],
@@ -227,6 +252,15 @@ export const EditorToolbar = () => {
       title: t('Validate').toString(),
       type: 'iconButton',
     },
+    {
+      group: 'ui',
+      icon: 'validate',
+      onClick: () => {
+        const externalWindow = window.open(window.location.origin + '/imageviewer', '', 'width=600,height=400,left=200,top=200');
+      },
+      title: t('Second Window Image Viewer').toString(),
+      type: 'iconButton',
+    },
     { group: 'ui', type: 'divider', hide: isReadonly },
     {
       group: 'ui',
diff --git a/packages/cwrc-leafwriter/src/js/layout/panels/imageViewer/index.ts b/packages/cwrc-leafwriter/src/js/layout/panels/imageViewer/index.ts
index d72fc5d826df3427c14f1a2e24ca3a33d6108562..8740534c7ae26ce4ef137c208c94f516dab71ca6 100644
--- a/packages/cwrc-leafwriter/src/js/layout/panels/imageViewer/index.ts
+++ b/packages/cwrc-leafwriter/src/js/layout/panels/imageViewer/index.ts
@@ -6,6 +6,7 @@ import { Octokit } from '@octokit/rest';
 import { Buffer } from 'buffer/';
 import axios, { AxiosInstance, AxiosResponse } from 'axios';
 import i18next from '../../../../i18n';
+import { BroadcastChannel } from 'broadcast-channel';
 
 const { t } = i18next;
 
@@ -25,17 +26,23 @@ class ImageViewer {
 
   readonly osd: ReturnType<typeof OpenSeaDragon>;
 
+  readonly channel: any;
+
   $pageBreaks: any;
   $oldPageBreaks: any;
   currentIndex = -1;
   ignoreScroll = false;
   inhibitScroll = false // Marker to inhibit scrolling when user has zoomed in on a particular image
 
+  globalTileSources: any;
+
   constructor({ attribute, parentId, tag, writer }: ImageViewerProps) {
     this.writer = writer;
     this.id = `${parentId}_imageViewer`;
     this.tagName = tag ?? 'pb'; // page break element name
     this.attrName = attribute ?? 'facs'; // attribute that stores the image URL
+    this.channel = new BroadcastChannel('imageViewer-channel');
+    this.channel.onmessage = this.handleMessage;
 
     const _this = this;
 
@@ -149,6 +156,14 @@ class ImageViewer {
     });
   }
 
+  
+  private handleMessage = (event) => {
+    console.log(event)
+    if (event.imageViewerWindowReady && event.imageViewerWindowReady == true) {
+      this.channel.postMessage({tileSources: this.globalTileSources})
+    }
+  };
+
   // ensure page break tags are display block
   private cssHack() {
     if (!this.writer.editor) return;
@@ -451,6 +466,8 @@ class ImageViewer {
       }
     }
 
+    this.globalTileSources = tileSources
+
     this.osd.open(tileSources);
 
     // tileSources.length === 0