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`