Reputation: 55
I am building an electron app with react.js. It works fine in development mode but does not work in production mode. I have added the main folder inside the public and you can see my production error in the URL in the main.js code.
My folder structure
My main.js code -
const { app, BrowserWindow, globalShortcut, shell } = require("electron");
const isDev = require("electron-is-dev");
const path = require("path");
const getIconPath = () => {
let ext = "png";
if (process.platform === "darwin") {
ext = "icns";
}
if (process.platform === "linux") {
ext = "png";
}
if (process.platform === "win32") {
ext = "ico";
}
let iconPath;
iconPath = isDev
? path.join(__dirname, "..", "assets", "app_icon", `icon.${ext}`)
: path.join(
__dirname,
"..",
"..",
"build",
"assets",
"app_icon",
`icon.${ext}`
);
return iconPath;
};
let mainWindow;
let splash;
function createWindow() {
splash = new BrowserWindow({
width: 600,
height: 400,
autoHideMenuBar: true,
center: true,
transparent: true,
frame: false,
show: false,
maximizable: false,
resizable: false,
minimizable: false,
alwaysOnTop: true,
});
mainWindow = new BrowserWindow({
minWidth: 500,
minHeight: 300,
show: false,
autoHideMenuBar: true,
icon: isDev ? getIconPath() : null,
webPreferences: {
contextIsolation: false,
nodeIntegration: true,
},
});
const mainWindowURL = isDev
? "http://localhost:3000"
: `file://${path.join(__dirname, "../", "../build/index.html")}`;
const splashURL = isDev
? "http://localhost:3000/splash"
: `file://${path.join(__dirname, "../", "../build/index.html#/splash")}`;
splash.loadURL(splashURL);
mainWindow.loadURL(mainWindowURL);
splash.once("ready-to-show", () => {
splash.show();
});
mainWindow.once("ready-to-show", () => {
setTimeout(() => {
splash.destroy();
// maximize the window
mainWindow.maximize();
mainWindow.show();
}, 3000);
});
// production a bad jabe
const handleDevTools = () => {
if (mainWindow.webContents.isDevToolsOpened()) {
mainWindow.webContents.closeDevTools();
} else {
mainWindow.webContents.openDevTools();
}
};
globalShortcut.register("CommandOrControl+Shift+I", handleDevTools);
// mainWindow.webContents.openDevTools();
mainWindow.on("closed", () => {
mainWindow = null;
});
}
app.on("ready", createWindow);
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("activate", function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
My router.js code with react-router-dom
import Splash from "../pages/Splash/Splash";
import Home from "../pages/Home/Home";
import Login from "../pages/Login/Login";
import Register from "../pages/Register/Register";
import { createBrowserRouter } from "react-router-dom";
const router = createBrowserRouter([
{
path: "/",
children: [
{
path: "/",
element: <Home />,
},
{
path: "/splash",
element: <Splash />,
},
{
path: "/login",
element: <Login />,
},
{
path: "/register",
element: <Register />,
},
],
},
]);
export default router;
And when I run the project in production mode built by electron-builder. This shows up the
error - Unexpected Application Error! 404 Not Found
Upvotes: 2
Views: 5740
Reputation: 1
I encountered the same issue and the solution was simple. You just need to replace the createBrowserRouter
with createHashRouter
in your app.js
and everything should work perfectly.
Upvotes: 0
Reputation: 2380
After having this issue for a few days I finally discovery the electron-router-dom
It solves all issues using react router with Electron.
const { createFileRoute, createURLRoute } = require("electron-router-dom");
...
if (process.env.ELECTRON_START_URL) {
mainWindow.loadURL(createURLRoute(process.env.ELECTRON_START_URL, "main"));
} else {
mainWindow.loadFile(
...createFileRoute(path.join(__dirname, "../build/index.html"), "main")
);
}
and on your App.js
import { Router, Route } from "electron-router-dom";
...
<Router
main={
<>
<Route
path="/"
element={<Login />}
/>
<Route
path="/home"
element={<Home />}
/>
<Route path="/dashboard" element={<Dashboard />} />
</>
}
/>
Upvotes: 0
Reputation: 7801
Your splash window's url uses a hash (#
), yet you use createBrowserRouter
. Routing on Electron and React only works with HashRouter
, so you should replace createBrowserRouter
with createHashRouter
.
Additionally, you might need to write the hash path outside of path.join()
:
`file://${path.join(__dirname, "../", "../build/index.html")}#/splash`
Upvotes: 9