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 . Instead, I focused on how to use [Browser View](https://www.electronjs.org/docs/latest/api/browser-view) with Electron.

The target? Get something similar to this: being able to load external pages into Electron, while maintaining control of the Browser Window.

electron-browser-view-01.gif

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:

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 Card.svelte component:

The important part is the function to call on the click:

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

I create 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 openInNewWindow() function:

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 addBrowserView and setIpcMainView methods:

Create a BrowserWiew in Electron

Now I have to define these methods. To do I change the CustomWindow class (src\electron\customWindow.ts).

First I add the browserView property:

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:

electron-browser-view-02.gif

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:

electron-browser-view-03.gif

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 src\electron\preload.ts:

Finally I allow only the main window to create new windows. To do this I edit src\electron\index.ts:

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: