I want to know how to open a web link in the default browser when clicked on a button in an electron app. Can anyone help me?
At the top of your main.js, make sure the following variables are defined:
const ipc = ipcMain;
const { app, BrowserWindow, ipcMain, webContents } = require('electron');
Inside your button onclick function (in the renderer), use the following:
ipc.send('SomeEvent');
Also make sure the following are defined in your renderer
const { ipcRenderer } = require('electron');
const ipc = ipcRenderer;
Then, use the following to open in the external browser (it will open in the user's default)
ipc.on('SomeEvent', ()=>{
require('electron').shell.openExternal('<LINK_HERE>');
})
Related
in my Game Launcher Electron project I was trying to open a subwindow with a buttonclick, and in there, offer additional features. These features include for example: opening exe files. For this I need node.js so I've tried to create methods for this in the preload script and expose them via contextBridge. These methods work fine in the main BrowserWindow. However, they are not reachable from the subwindow (Uncaught ReferenceError: game is not defined). See the code below:
preload.js
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
const { BrowserWindow } = require('electron');
contextBridge.exposeInMainWorld(
'game', {
open: () => {
console.log('test');
},
openAddGamePage: () => {
console.log('test');
}
}
);
renderer.js (script for main window), the exposed methods work fine here.
document.getElementById('openAddGameWindow').addEventListener('click', () => {
const childWindow = window.open('features/addGame/addGamePage.html', '_blank', 'nodeIntegration=yes')
game.open()
game.openAddGamePage()
})
addGame.js (script from addGamePage.html): The methods dont work here
document.getElementById('addGameButton').addEventListener('click', () => {
game.open()
})
I also tried to include the functions directly in the "addGame.js" and enable nodeIntegration when creating the child window, however this did not work either (require is not defined)
Trying to develop a small app using python flask and electron JS, basically i am using electron for only to run Flask Python Script by using (child_process & Spawn) in electron main.js file also using (LoadURL(http://localhost:5000)) instead of using (loadURL(index.html)).
I did close the Browser Window using simple (Window.Close()) function in separate JavaScript file which is linked in the body section, but cant figure out how to MINIMIZE the Browser Window using only JavaScript or Python in the same file linked in body.
Cant use electron for this because i am not using index.html in loadURL.
Appreciate all the help i cant get on this.
You should use a preload script and inter-process Communication
It's as simple as this
// in the preload script
// you can access Electron's renderer process modules here
const { contextBridge, ipcRenderer } = require('electron')
// you should handle the IPC call in the main process
// and call Electron's browserWindow.minimize() function
contextBridge.exposeInMainWorld('minimize', () => ipcRenderer.send('minimize'))
// in the main process, you should have something like this
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('minimize', () => {
mainWindow.minimize()
})
mainWindow.loadURL('https://example.com')
}
In your JavaScript file, you can now call window.minimize()
I have an electron app in which the Ui is built using react js. inside the react js ui other web app is loaded using the webview.
my problem is i need to save the data of the webview app when the electron app is closed.
I want to know how to access the onClose event of the electron app inside the webview app.
Just came upon something similar. You could do something like this.
In the Main process:
const { ipcMain, app, webContents } = require('electron')
app.on('will-quit', event => {
event.preventDefault()
let readyCount = 0
ipcMain.on('ready-to-quit', () => {
readyCount++
if (readyCount === allWebContents.length) {
app.exit()
}
})
const allWebContents = webContents.getAllWebContents()
allWebContents.forEach(contents => contents.send('app-will-quit'))
})
In the Renderer process:
const { ipcRenderer } = require('electron')
ipcRenderer.once('app-will-quit', () => {
// do stuff
ipcRenderer.send('ready-to-quit')
})
For my electron app, I would like to open another Svelte-window (or load different windows/components depending on the startup variables).
So let's say I used this tutorial to set up a basic structure, with my App.svelte looking like this:
<script>
const openLauncher = () => {
window.api.openWindow("launcher");
};
</script>
<button on:click={openLauncher}>Open Launcher</button>
As you can see, I added an IPC function to open a new window. The corresponding index.js:
const { app, BrowserWindow, ipcMain } = require("electron");
const { join } = require("path");
app.on("ready", () => {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
mainWindow.loadFile(join(__dirname, "../public/index.html"));
});
ipcMain.on("openLauncher", (event, args) => {
const launcher = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
launcher.loadFile(join(__dirname, "../public/launcher.html"));
});
preload.js:
const { contextBridge, ipcRenderer } = require("electron");
const API = {
openWindow: (obj) => ipcRenderer.send("openLauncher", obj),
}
contextBridge.exposeInMainWorld("api", API);
This does work and opens a new window with the launcher.html, but I can't figure out how to get the Svelte components working in that new file.
One idea I had was modifying main.js file so that the body component changes, like so:
import App from './App.svelte';
import LauncherApp from './LauncherApp.svelte';
const bodyID = document.getElementsByTagName('body')[0].id;
const app = {};
if (bodyID == "index") {
app = new App({
target: document.body,
});
}
else if (bodyID == "launcher") {
app = new LauncherApp({
target: document.body,
});
}
export default app;
This works for the main window (i.e. if I switch the IDs, it loads the correct component at startup) but since it doesn't load any Svelte whe opening the new window, this doesn't work.
So I would really appreciate any ideas on how to get Svelte to load for new/different windows/html-files! And if there is a way to do this with SvelteKit, even better!
Thank you in advance!
The obvious quick fix I see is using an #if block on bodyID in App.svelte containing two components, MainApp (content of App.svelte) and LauncherApp, and then simply changing bodyID depending on in which mode you are.
When using sveltekit I think it would make sense to treat LauncherApp as a separate route (I believe this is the only way to have "separated" pages with sveltekit, though I am not 100%). So when opening a new window you navigate the new instance of your application to the LauncherApp route. If you don't want the same base layout as in the main app, you can add a __layout.reset.svelte file.
I don't know why your solution didn't work, it was quite elegant.
As this post helped me alot to create seperate windows using Svelte and Electron, i just had to create my account after lurking Stack Overflow for years. I think i've cracked your problem without the "hackery" workaround.
I got it working without the #IF statements in my original App.svelte. This is how i did it:
My main.js in the src map (renderer side) is as follows:
import App from './App.svelte';
import Window2 from './Window2.svelte';
let bodyID = document.getElementsByTagName('body')[0].id;
let app;
if (bodyID == "index"){
app = new App({
target: document.body,
});
}
else if (bodyID == "window2"){
app = new Window2({
target: document.body,
});
}
export default app;
I think however that the real magic happens in my index.html and Window2.html. I made mine using the excellent YouTube videos provided by Tylerlaceby.
Basicly, the index.js in the main folder (so the Electron main js) opens the window with the following lines:
const main_window = new BrowserWindow({//Your settings
});
main_window.loadFile(join(__dirname, "../public/index.html"));
main_window.on("ready-to-show", main_window.show);
And the index.html that is in the public folder contains the following head:
`
<title>Main Window</title>
<link rel='icon' type='image/png' href='./favicon.ico'>
<link rel='stylesheet' href='global.css'>
<link rel='stylesheet' href='build/bundle.css'>
<script defer src='build/bundle.js'></script>
The body is empty, but has the id attached which i use in the main.js renderer side script.
I believe that the header in the index.html loads the build folder after the electron app has been build, containing all of your converted Svelte files.
The Window2.html is the same. The secondary window loads it the same way as the main window does in the second code block from the main.js on the electron side but refers to the Window2.html. The Window2.html contains a body with the ID Window2.
If the above is not the solution, it could also be because i use let instead of const. Once a variable has been assigned to const, it cannot be changed which might explain why it works the first time, but not the second time.
I'm sorry if i did not get all the formatting and refering to previous awnsers correctly. I'm still using to learn Stackoverflow but was eager to share how i made it work for me.
I am trying to make an electron app and I need to load a HTML to a BrowserWindow but the script that controls this is in another Directory which isn't the same as the HTML's ones.
This is how it looks:
This is my code to load the HTML into the BrowserWindow:
const electron = require("electron");
const {BrowserWindow} = electron;
//This part is called from an exported function
const window = new BrowserWindow();
window.setSize(500 , 500);
window.show();
window.setMenu(null);
window.loadFile("../HTML/MainWindow.html");
The window is created but it doesn't load the HTML into it which is really weird, someone help? By the way keep in mind that I don't create the window from the main script.
Try with this
var path = require('path');
window.loadURL(path.join(__dirname, '../HTML/MainWindow.html'))
So I managed to solve the problem by importing path like what #Luis Daniel Sandi talled me to do and then I just did: window.loadURL(path.join(__dirname, '../HTML/MainWindow.html')) and instead of importing BrowserWindow from electron I imported that from electron.remote.