I'm using the BrowserWindow to display an app and I would like to force the external links to be opened in the default browser. Is that even possible or I have to approach this differently?
12 Answers
Update: this does not work in electron >= 22 because on('new-window'
has been removed.
I came up with this, after checking the solution from the previous answer.
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
require('electron').shell.openExternal(url);
});
According to the electron spec, new-window
is fired when external links are clicked.
NOTE: Requires that you use target="_blank"
on your anchor tags.

- 2,431
- 21
- 32

- 1,566
- 1
- 9
- 3
-
4doesn't `new-window` only fire when `target` is set to `_blank`? – Yan Foto Sep 06 '15 at 21:11
-
1@YanFoto maybe my bad.. but by external I meant that.. I tried the `will-navigate` but it didn't work in my case.. – Lipis Sep 06 '15 at 21:24
-
@lipis now i get it! I thought you meant everything which is not local :D – Yan Foto Sep 06 '15 at 21:26
-
1Don't know what ```shell``` should be but I used the npm node module https://www.npmjs.com/package/open to open the external link. So my code looks exactly the same instead of line ```require('shell').openExternal(url);``` that is ```var open = require('open'); open(url);``` – Frank Roth Jul 04 '16 at 08:45
-
2Instead of `require('shell')`, which threw an error for me, I was able to get this to work using `electron.shell.openExternal(url);` – Doug Aug 22 '16 at 16:15
-
8`main` is the window returned when you create your browser window with `new BrowserWindow()` – edrian Dec 27 '16 at 16:48
-
1@Doug `shell` is a part of `electron`, not a separate module. So you need to use `require( "electron" ).shell` or `const { shell } = require( "electron" )` – Joshua Pinter Sep 04 '18 at 13:57
-
2`new-window` is deprecated in Electron 12. See https://stackoverflow.com/a/67409223/1394731 – theicfire May 05 '21 at 21:57
new-window
is now deprecated in favor of setWindowOpenHandler
in Electron 12 (see https://github.com/electron/electron/pull/24517).
So a more up to date answer would be as follows, this goes in your 'entry point' file for example main.js
:
const mainWindow = new BrowserWindow()
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
See also the electron docs Native window
example.
This will affect all links in your electron app that have target="_blank"
set.
-
-
Thank you! Saved me some time to configure it myself while checking the official electron documentation: new-window -> `Deprecated in favor of webContents.setWindowOpenHandler.` https://www.electronjs.org/docs/latest/api/web-contents#event-new-window-deprecated – Zdravko Kolev Dec 08 '21 at 13:25
-
2Ensure that you are importing `shell` from electron: const { shell } = require('electron') https://www.electronjs.org/docs/latest/tutorial/security#how-12 – Zdravko Kolev Dec 08 '21 at 13:32
-
If I write an url like `www.foo.com` , it will open `localhost:3000/www.foo.com`. How to only open the link without the localhost prefix? – DoneDeal0 Jan 29 '23 at 20:17
-
2
-
-
1if you are on es6, import shell with `import { shell } from 'electron'` – chia yongkang Feb 17 '23 at 22:11
-
Improved from the accepted answer ;
- the link must be
target="_blank"
; add in
background.js
(or anywhere you created your window) :window.webContents.on('new-window', function(e, url) { // make sure local urls stay in electron perimeter if('file://' === url.substr(0, 'file://'.length)) { return; } // and open every other protocols on the browser e.preventDefault(); shell.openExternal(url); });
Note : To ensure this behavior across all application windows, this code should be run after each window creation.

- 1,552
- 2
- 15
- 22
-
Good point on the `target` - electron calls the 'entry point' where you create your window `main.js` - see their [Quick Start scaffolding](https://www.electronjs.org/docs/latest/tutorial/quick-start#scaffold-the-project) docs – icc97 Aug 24 '23 at 13:16
-
If you're not using target="_blank"
in your anchor
elements, this might work for you:
const shell = require('electron').shell;
$(document).on('click', 'a[href^="http"]', function(event) {
event.preventDefault();
shell.openExternal(this.href);
});

- 4,101
- 1
- 31
- 22
I haven't tested this but I assume this is should work:
1) Get WebContents
of the your BrowserWindow
var wc = browserWindow.webContents;
2) Register for will-navigate
of WebContent
and intercept navigation/link clicks:
wc.on('will-navigate', function(e, url) {
/* If url isn't the actual page */
if(url != wc.getURL()) {
e.preventDefault();
openBrowser(url);
}
}
3) Implement openBrowser
using child_process
. An example for Linux desktops:
var openBrowser(url) {
require('child_process').exec('xdg-open ' + url);
}
let me know if this works for you!
-
@SkyzohKey you edited the condition from pseudo code that said "If url is external"; did you actually test that `url != wc.getURL()` is helpful? I imagine it would always be true. – 1j01 Aug 24 '18 at 22:13
For anybody coming by.
My use case:
I was using SimpleMDE in my app and it's preview mode was opening links in the same window. I wanted all links to open in the default OS browser. I put this snippet, based on the other answers, inside my main.js file. It calls it after it creates the new BrowserWindow instance. My instance is called mainWindow
let wc = mainWindow.webContents
wc.on('will-navigate', function (e, url) {
if (url != wc.getURL()) {
e.preventDefault()
electron.shell.openExternal(url)
}
})

- 79
- 1
- 5
Check whether the requested url is an external link. If yes then use shell.openExternal
.
mainWindow.webContents.on('will-navigate', function(e, reqUrl) {
let getHost = url=>require('url').parse(url).host;
let reqHost = getHost(reqUrl);
let isExternal = reqHost && reqHost != getHost(wc.getURL());
if(isExternal) {
e.preventDefault();
electron.shell.openExternal(reqUrl);
}
}

- 24,167
- 8
- 82
- 93
-
-
@vsecades Which version do you mean? There is no issue as my test on electron electron v26.0.0 and v19.1.9 – cuixiping Aug 02 '23 at 15:09
Put this in renderer side js
file. It'll open http
, https
links in user's default browser.
No JQuery attached! no target="_blank"
required!
let shell = require('electron').shell
document.addEventListener('click', function (event) {
if (event.target.tagName === 'A' && event.target.href.startsWith('http')) {
event.preventDefault()
shell.openExternal(event.target.href)
}
})

- 42,508
- 29
- 229
- 225
For Electron 5, this is what worked for me:
In
main.js
(where you create your browser window), include 'shell' in your main require statement (usually at the top of the file), e.g.:// Modules to control application life and create native browser window const { BrowserWindow, shell } = require('electron');
Inside the
createWindow()
function, aftermainWindow = new BrowserWindow({ ... })
, add these lines:mainWindow.webContents.on('new-window', function(e, url) { e.preventDefault(); shell.openExternal(url); });

- 6,499
- 5
- 38
- 57

- 437
- 3
- 6
I solved the problem by the following step
- Add shell on
const {app, BrowserWindow} = require('electron')
const {app, BrowserWindow, shell} = require('electron')
- Set nativeWindowOpen is true
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 1350,
height: 880,
webPreferences: {
nativeWindowOpen: true,
preload: path.join(__dirname, 'preload.js')
},
icon: path.join(__dirname, './img/icon.icns')
})
- Add the following listener code
mainWindow.webContents.on('will-navigate', function(e, reqUrl) {
let getHost = url=>require('url').parse(url).host;
let reqHost = getHost(reqUrl);
let isExternal = reqHost && reqHost !== getHost(wc.getURL());
if(isExternal) {
e.preventDefault();
shell.openExternal(reqUrl, {});
}
})
reference https://stackoverflow.com/a/42570770/7458156 by cuixiping

- 421
- 5
- 6
-
Hi, please where should the listener code be placed ? Inside the html, main.js or preload.js ? – GBETNKOM NJIFON Dec 30 '22 at 08:41
I tend to use these lines in external .js
script:
let ele = document.createElement("a");
let url = "https://google.com";
ele.setAttribute("href", url);
ele.setAttribute("onclick", "require('electron').shell.openExternal('" + url + "')");

- 33
- 6
If you are using new window using window.open()
then use the setWindowOpenHandler
as new-window
is depreciated.
I was working on react and had to open my component in new window. Also, this window does not have a url I used the frameName
property to open the browserWindow in electron. However you may use url
also inside if condition block.
window.open("", "CallWindow", features);
mainWindow.webContents.setWindowOpenHandler(({ frameName }) => {
// Dynamically give position to opened window
const leftPos = screen.getPrimaryDisplay().size.width - 420;
const topPos = 60;
if (frameName === "CallWindow") {
return {
action: "allow",
overrideBrowserWindowOptions: {
width: 360,
height: 728,
minWidth: 220,
minHeight: 220,
x: leftPos,
y: topPos,
autoHideMenuBar: true,
},
};
}
return { action: "deny" };
});
Following link shows how to use setWindowOpenHandler
.
https://github.com/electron/electron/blob/main/docs/api/window-open.md

- 98
- 7