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
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`