Problem
Currently I’m setting up an electron app with React and typescript.
The idea is to load in my React PWA, in which it is possible to have links to external sources.
I want to prevent my electron app from navigating to it, but instead open up the browser on the device itself.
The problem I’m having is that the second time you click a link, the app crashes.
Tried sollutions
I’ve tried the following options for implementing this:
Within webview itself
My app is loaded in a webview, which I tried to extend like this:
// appview.tsx
import React, { useEffect, useRef } from 'react';
import { join } from 'node:path';
import * as Styled from './app-view.style';
export type AppViewProps = {
url: string;
};
export const AppView: React.FC<AppViewProps> = ({ url }) => {
const webviewRef = useRef<HTMLWebViewElement>(null);
useEffect(() => {
const webview = webviewRef.current;
if (webview) {
const preventNavigate = () => {
webview.stop(); // first navigate it will stop, second crashes the main javascript process
};
webview.addEventListener('will-navigate', preventNavigate);
return () => {
webview.removeEventListener('will-navigate', preventNavigate);
}
}
}, []);
return (
<Styled.Container>
<webview
ref={webviewRef}
src={url}
preload={`file:${join(process.env.VITE_PUBLIC, './preload.js')}`}
style={{ width: '100%', height: '100%' }}
nodeintegration="true"
allowpopups="true"
/>
</Styled.Container>
);
};
Main Process
In my main.ts
file I tried to catch the will-navigate
and execute preventDefault()
on the given event. I get the exact same error as in the webview here.
// main.ts
...
function createWindow() {
win = new BrowserWindow({
icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'),
titleBarStyle: isMac ? 'hidden' : 'default',
frame: isLinux,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webviewTag: true,
spellcheck: false,
},
});
// Test active push message to Renderer-process.
win.webContents.on('did-finish-load', () => {
win?.webContents.send('main-process-message', (new Date).toLocaleString())
})
if (VITE_DEV_SERVER_URL) {
win.loadURL(VITE_DEV_SERVER_URL)
} else {
// win.loadFile('dist/index.html')
win.loadFile(path.join(RENDERER_DIST, 'index.html'))
}
win.webContents.on('did-attach-webview', (_, contents) => {
contents.on('will-navigate', (details) => {
console.log('navigation', details.url, details.frame);
details.preventDefault();
// shell.openExternal(details.url);
})
});
}
...
The crash
What is going on and is there a way to prevent my app from crashing?