One of the problems I’m facing with my gest-dashboard project is managing several windows with Electron. It is a more complex problem than I thought and it prompted me to study the issue. After some testing I discarded <iframe> and
The target? Get something similar to this: being able to load external pages into Electron, while maintaining control of the Browser Window.
Since this post is about a very specific topic I don’t cover all the steps to set up a new Electron project. For simplicity, I have used the el3um4s/memento-svelte-electron-typescript template but it is not mandatory. Instead it is important to understand one thing, before starting: how to use ipcMain and ipcRenderer to make the various windows communicate with Electron. There are some interesting guides on the net. In this tutorial I start from this:
But first: why use a browser view?
The question must be answered: why use a browser view instead of a simpler webview tag?
The question must be answered: why use a browser view instead of a simpler  tag (https://www.electronjs.org/docs/latest/api/webview-tag)?
The first reason is that Electron’s own documentation recommends doing this. The web views are now being discontinued. To quote developer.chrome:
chrome.webviewTag: This API is part of the deprecated Chrome Apps platform. Learn more about migrating your app.
It follows that it is better to turn to other shores. An interesting solution is to use
iframes. Unfortunately it creates more problems than it solves. Maybe in the future I will do more in-depth tests.
Fortunately, the problem has already been solved by others smarter than me. I recommend reading these two stories, they are very informative:
- Slack Engineering - Growing Pains: Migrating Slack’s Desktop App to BrowserView
- Figma - Introducing BrowserView for Electron
Summarizing what I need, and what I believe the Browser Views can give me, is a method for:
- view pages external to Electron
- integrate these pages into the application
- use the ipcMain-ipcRenderer system from external pages
That said, go with the code!
The graphical interface
The first thing I need is a button. For aesthetic reasons I created a
The important part is the function to call on the
I send the
openInNewWindow command from the renderer with the details that interest me (the
link of the page to open). But I have to create a special API.
Add the WindowManager API
src\electron\IPC\windowManager.ts. First I import the core libraries of my API:
Then I define the name to use to call it:
Then I define the open channels in output, the ones to be used to send the commands from the window
Then it’s up to the incoming channels, the ones that can be used to send a response to the window. For simplicity in this example I leave the list empty:
Finally I initialize the API and export it:
Define the commands to execute
Obviously this is not enough. I need to actually define the command to run. To do this I create the
This way if I click a button from the main window I can create a new window.
I have to point out one thing. I imported the module
src\electron\globals.ts to make it easier to pass the url of the start page:
This way I can call the main page from any module.
But I’m not done yet. I’d better give the new window some “special powers”. At least the ability to use the titlebar buttons:
All that remains is to add a Browser View to the new window. I call the
Create a BrowserWiew in Electron
Now I have to define these methods. To do I change the
CustomWindow class (
First I add the
The general procedure for creating and adding the Browser View in Electron is this:
Starting from this I add a method to my class:
I have set the position to
x = 1 and
y = 32 because I want to leave space for the title bar in the main window.
There is a small detail to solve:
If I change the size of the window, the size of the Browser View does not change. And the dimensions are not what I want.
First I make sure the size is correct at startup using BrowserWindow.getSize()
Then I use BrowserView.setAutoResize(options) to automatically change the size when the BrowserWindow changes:
To complete everything I have to allow the BrowserView to access the API:
Register WindowManager API
It is not enough to define the WindowManager API, I also need to enable it in
Finally I allow only the main window to create new windows. To do this I edit
Well, after completing all these steps I can open a new window, with a BrowserView embedded, using a simple line of code:
As usual, the project code is freely available on GitHub
I also created a list with my articles on ElectronJS: