Is there any (simple/built-in way) to open a new browser (I mean default OS browser) window for a link from Electron instead of visiting that link inside your Electron app ?
-
1Does this answer your question? [How can I force external links from browser-window to open in a default browser from Electron?](https://stackoverflow.com/questions/32402327/how-can-i-force-external-links-from-browser-window-to-open-in-a-default-browser) – m4tt1mus Mar 27 '20 at 20:03
-
One of this one or the [linked one](https://stackoverflow.com/questions/32402327/how-can-i-force-external-links-from-browser-window-to-open-in-a-default-browser) from @m4tt1mus should be closed. They are exactly the same question. This was asked earlier - but I don't know what is the defining criteria. – icc97 Aug 24 '23 at 13:28
12 Answers
You can simply use :
require("shell").openExternal("http://www.google.com")

- 3,642
- 3
- 28
- 37
-
28Better answer over here: http://stackoverflow.com/questions/32402327/how-can-i-force-external-links-from-browser-window-to-open-in-a-default-browser – Greg Bell Nov 19 '15 at 00:58
-
-
1@John It wouldn't be a big deal, but I'd take hints from other Electron apps and see how they handle links. Discord and Slack open links in the browser (non-mobile), and I think that's a good precedent. – MusicDev Aug 14 '19 at 14:43
-
How to open an external link through electron app but with a specific choosed browser, for example chrome? I dont want to change my settings and I dont want to open with explorer ( my default browser)... @zianwar #help someone ? – almightysosa Dec 27 '19 at 10:20
-
What if I want to open an external website across all the browser? For ex: Chrome, Mozilla, and Edge? – praveenbharatsagar Aug 01 '22 at 10:46
-
This answer doesn't explain how or where you should use this. [@Evgenii's answer here](https://stackoverflow.com/a/67108615/327074) should be the accepted one. – icc97 Aug 24 '23 at 13:30
EDIT: @Evgenii's answer is much better these days.
This answer is quite old and assumes you have jQuery.
const shell = require('electron').shell;
// assuming $ is jQuery
$(document).on('click', 'a[href^="http"]', function(event) {
event.preventDefault();
shell.openExternal(this.href);
});
Update
on('new-window'..
is deprecated since electron 22. use setWindowOpenHandler
instead. Check other answers.
deprecation info: https://www.electronjs.org/docs/latest/breaking-changes#removed-webcontents-new-window-event
old Answer (pre electron 22)
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
require('electron').shell.openExternal(url);
});
Requires that you use target="_blank" on your anchor tags.

- 2,431
- 21
- 32

- 5,303
- 3
- 20
- 20
-
1Any method to handle links without target="_blank"? Maybe one way is to add `
` to head https://stackoverflow.com/a/24428525/2129219 – Colin D Aug 27 '21 at 19:17 -
"new-window" is deprecated since electron 22. use this answer instead: https://stackoverflow.com/a/67108615/4394435 https://www.electronjs.org/docs/latest/breaking-changes#removed-webcontents-new-window-event – Welcor Mar 09 '23 at 21:15
My code snippet clue accordingly to the depreciations in Electron version ^12.0.0, put this code in your 'entry point' main.js
(or whatever you call it):
const win = new BrowserWindow();
win.webContents.setWindowOpenHandler(({ url }) => {
// config.fileProtocol is my custom file protocol
if (url.startsWith(config.fileProtocol)) {
return { action: 'allow' };
}
// open url in a browser and prevent default
shell.openExternal(url);
return { action: 'deny' };
});
Links must also have target="_blank"
.
-
3In case someone wants to know the "deny" and "allow" rules. https://www.electronjs.org/docs/api/web-contents#contentssetwindowopenhandlerhandler – ssi-anik Jun 13 '21 at 07:15
-
This should be the accepted answer now - it has a mirror answer in the similar question - https://stackoverflow.com/a/67409223/327074. – icc97 Aug 24 '23 at 13:26
To make all Electron links to open externally in the default OS browser you will have to add an onclick
property to them and change the href
property so it doesn't load anything in the Electron app.
You could use something like this:
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}
But make sure the entire document has loaded before doing this otherwise it is not going to work. A more robust implementation would look like this:
if (document.readyState != "complete") {
document.addEventListener('DOMContentLoaded', function() {
prepareTags()
}, false);
} else {
prepareTags();
}
function prepareTags(){
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}
return false;
}
Remember that if you load external files you will have to make them go through this process as well after they are fully loaded.

- 9,819
- 3
- 35
- 41
-
3You should learn about event delegation, which only requires one event listener, can handle newly created elements without extra code, and is more efficient. You shouldn't use the `onclick` attribute to define an event listener; you should use `addEventListener` instead. You've introduced a security vulnerability, which can be demonstrated with `exploit`. (Finally, there are also alternative solutions to this problem that don't involve the DOM at all) – 1j01 Aug 24 '18 at 22:02
-
4@1j01 You managed to be rude and condescending without actually providing a better answer. This is a forum, if you have a more reliable solution, please answer the OP so others can also benefit from the knowledge. – Marcelo Lazaroni Aug 25 '18 at 23:43
-
2I'm not trying to be rude; I meant what I said in earnest. I was trying to fit within the comment length limit which distracted me from how to best present what I was trying to say in polite way (that comes across as polite). Maybe I should have split it into multiple comments... Also I should use less "you" statements, for sure. – 1j01 Sep 10 '18 at 22:56
-
3**Rephrased:** A better way to listen for click events for all links would be [event delegation](https://javascript.info/event-delegation), which only requires one listener, and works with newly created elements without special handling. Also, you shouldn't use the `onclick` attribute. The concatenation of code together with data here introduces a security vulnerability where a third party could potentially execute arbitrary code. [Here's a demonstration.](http://jsfiddle.net/1j01/6evh0n8r/) – 1j01 Sep 10 '18 at 23:53
-
1**Rephrasing continued:** [`addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) is preferred over `onclick` because it allows multiple event listeners to be added to the same element, but you could also use [`element.onclick = function(){ ... }`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) if you don't need to worry about listeners being overwritten. – 1j01 Sep 10 '18 at 23:58
-
Also if you *do* ever need to embed data in JS code, you could use [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) (which works on strings as well as objects), e.g. `"require('shell').openExternal(" + JSON.stringify(aTags[i].href) + ")"` – 1j01 Sep 11 '18 at 00:01
Some handy solutions can be found in this gist.
By listening on the body, the following solutions will work on <a>
tags that may not yet exist when the JavaScript runs, but only appear in the DOM at a later time.
This one by luizcarraro requires jQuery:
$('body').on('click', 'a', (event) => {
event.preventDefault();
require("electron").shell.openExternal(event.target.href);
});
You can change the selector to target only certain links, e.g. '#messages-view a'
or 'a.open-external'
.
Here is an alternative without any library (derived from zrbecker's):
document.body.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') {
event.preventDefault();
require("electron").shell.openExternal(event.target.href);
}
});
Consult the gist for more examples.

- 29,306
- 13
- 121
- 110
-
1I used the following test: `if (event.target.href && event.target.href.match(/^https?:\/\//))`. – Manngo Dec 23 '20 at 05:47
I use this method with Electron v.13.
We intercept the user's navigation (window.location
) and open the URL in the default browser.
See the doc : https://www.electronjs.org/docs/latest/api/web-contents#event-will-navigate
const { shell } = require('electron');
window.webContents.on('will-navigate', function (e, url) {
e.preventDefault();
shell.openExternal(url);
});

- 131
- 1
- 5
-
Your answer could be improved by providing information on what the code does and how it helps the OP. – Tyler2P Dec 21 '21 at 09:55
In the view component use simple a
link:
<a href="https://google.com" target="_blank" rel="noreferrer">
<button type="button">
button title
</button>
</a>
And in file public/electron.js
add default behavior for all a
link navigations:
function createWindow() {
...
// Open urls in the user's browser
win.webContents.setWindowOpenHandler((edata) => {
shell.openExternal(edata.url);
return { action: "deny" };
});
}

- 1,151
- 11
- 17
On tsx
syntax (Electron):
import { shell } from "electron";
shell.openExternal("http://www.google.com")

- 959
- 10
- 23
To open an external link in an Electron's Project you will need the module Shell (https://www.electronjs.org/docs/api/shell#shell) and the method openExternal
.
But if you are looking for an abstract way to implement that logic is by creating a handler for a custom target to your target attribute.
const {shell} = require('electron');
if (document.readyState != "complete") {
document.addEventListener('DOMContentLoaded', function() {
init()
}, false);
} else {
init();
}
function init(){
handleExternalLinks();
//other inits
}
function handleExternalLinks(){
let links = document.getElementsByTagName('a')
let a,i = 0;
while (links[i]){
a = links[i]
//If <a target="_external">, so open using shell.
if(a.getAttribute('target') == '_external'){
a.addEventListener('click',(ev => {
ev.preventDefault();
let url = a.href;
shell.openExternal(url);
a.setAttribute('href', '#');
return false;
}))
}
console.log(a,a.getAttribute('external'))
i++;
}
}

- 1,819
- 3
- 20
- 39
-
Is there any way to set watcher for openExternal(URL); I want to set watcher for opened page's specific URL and when I got that URL Need to close the browser window or tab? – Nikunj Beladiya Feb 03 '21 at 05:52
-
@NikunjBeladiya in this case you should set manually the attribute target="_external" for each link that you want to open in a new window. Or make a kind of switch in the identifier of your page. – LeonanCarvalho Feb 03 '21 at 12:56
Update 2023
Since electron 22 on('new-window')
is deprecated. You need to use setWindowOpenHandler
and add a target="_black" to your links
mainWindow.webContents.setWindowOpenHandler((details) => {
require("electron").shell.openExternal(details.url);
return { action: 'deny' }
})
To run an Electron project in your actual browser (Chrome, Mozilla, etc), add this to your script are external script:
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}

- 7,604
- 4
- 45
- 55
-
1You don't need more than one event listener (you can use event delegation which will handle newly created elements and be more efficient, and there are alternative solutions to this problem that don't involve the DOM at all). You shouldn't use the `onclick` attribute to define an event listener. You've introduced a security vulnerability, e.g. `exploit` - you should use `addEventListener` instead. (or at least e.g. `aTags[i].onclick = ()=> { require('shell').openExternal(this.href) }` which is very short, but destroys any existing listener added in this way) – 1j01 Aug 24 '18 at 21:55