How can I force external links from browser-window to open in a default browser from Electron?
node.jsElectronnode.js Problem Overview
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?
node.js Solutions
Solution 1 - node.js
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.
Solution 2 - node.js
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:
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
Solution 3 - node.js
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);
});
Solution 4 - node.js
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.
Solution 5 - node.js
I haven't tested this but I assume this is should work:
-
Get
WebContents
of the yourBrowserWindow
var wc = browserWindow.webContents;
-
Register for
will-navigate
ofWebContent
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!
Solution 6 - node.js
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)
}
})
Solution 7 - node.js
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);
}
}
Solution 8 - node.js
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)
}
})
Solution 9 - node.js
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); });
Solution 10 - node.js
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
Solution 11 - node.js
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 + "')");