Open external links in an Electron app using the system browser#
For Datasette.app I wanted to ensure that links to external URLs would open in the system browser.
This recipe works:
1function postConfigure(window) {2 window.webContents.on("will-navigate", function (event, reqUrl) {3 let requestedHost = new URL(reqUrl).host;4 let currentHost = new URL(window.webContents.getURL()).host;5 if (requestedHost && requestedHost != currentHost) {6 event.preventDefault();7 shell.openExternal(reqUrl);8 }9 });10}
The will-navigate
event fires before any in-browser navigations, which means they can be intercepted and cancelled if necessary.
I use the URL()
class to extract the .host
so I can check if the host being navigated to differs from the host that the application is running against (which is probably localhost:$port
).
Initially I was using require('url').URL
for this but that doesn’t appear to be necessary - Node.js ships with URL
as a top-level class these days.
event.preventDefault()
cancels the navigation and shell.openExternal(reqUrl)
opens the URL using the system default browsner.
I call this function on any new window I create using new BrowserWindow
- for example:
1mainWindow = new BrowserWindow({2 width: 800,3 height: 600,4 show: false,5});6mainWindow.loadFile("loading.html");7mainWindow.once("ready-to-show", () => {8 mainWindow.show();9});10postConfigure(mainWindow);