Ashikur Rahman Munna
Ashikur Rahman Munna

Reputation: 55

Electron React 404 not found in production

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

enter image description here

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

enter image description here

Upvotes: 2

Views: 5740

Answers (3)

Chamsedin azouz
Chamsedin azouz

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

Deivison Sporteman
Deivison Sporteman

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

Arkellys
Arkellys

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

Related Questions