Reputation: 21835
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?
Upvotes: 79
Views: 45918
Reputation: 3067
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.
Upvotes: 89
Reputation: 98
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
Upvotes: 0
Reputation: 1596
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.
Upvotes: 158
Reputation: 49
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 + "')");
Upvotes: 0
Reputation: 447
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, after mainWindow = new BrowserWindow({ ... })
, add these lines:
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
shell.openExternal(url);
});
Upvotes: 1
Reputation: 461
I solved the problem by the following step
const {app, BrowserWindow} = require('electron')
const {app, BrowserWindow, shell} = require('electron')
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')
})
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
Upvotes: 0
Reputation: 1636
Improved from the accepted answer ;
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.
Upvotes: 10
Reputation: 49540
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)
}
})
Upvotes: 2
Reputation: 25419
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);
}
}
Upvotes: 1
Reputation: 79
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)
}
})
Upvotes: 4
Reputation: 11388
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!
Upvotes: 4
Reputation: 4409
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);
});
Upvotes: 8