How to use React Router with Electron?

How to use React Router with Electron?

Using this boilerplate as reference I created an Electron app. It uses webpack to bundle the scripts and express server to host it.
Webpack config is practically same as this and server this.
Electron’s script loads:
mainWindow.loadURL(‘file://’ + __dirname + ‘/app/index.html’);
And index.html loads the script hosted by the server:

I run electron index.js to build the app and node server to start server which using webpack bundles the scripts.
It works fine, my React component App is mounted. But how I integrate react-router into this?
I implemented it the same way I would in a browser app. I get this error:
[react-router] Location “/Users/arjun/Documents/Github/electron-app/app/index.html” did not match any routes
It is taking file path as the route. Going through the boiler plate code did not help. What am I missing?

Solutions/Answers:

Solution 1:

Another option would be to use hashHistory instead. Actually, in your referenced repo you can see that they’re using hashHistory, how about trying that and posting back?

Related:  How to use ng-if with ng-repeat?

Solution 2:

I’m using React Router v4 and didn’t want to fallback to the HashRouter, so I solved it with something amongst the likes of:

import { Redirect, BrowserRouter } from 'react-router-dom';

const App = () => (
  <BrowserRouter>
    <div>
      {window.location.pathname.includes('index.html') && <Redirect to="/" />}
    </div>
  </BrowserRouter>
);

Solution 3:

Had to Replace BrowserRouter with HashRouter.

import {
  HashRouter,
  Route
} from "react-router-dom";

And then in my index.js or the entry file of the Electron app I had something like this:

<HashRouter>
  <div>
    <Route path="/" exact     component={ Home } />
    <Route path="/firstPage"  component={ FirstPage } />
    <Route path="/secondPage" component={ SecondPage } />
  </div>
</HashRouter>

And then everything just worked.

The reasoning: BrowserRouter is meant for request-based environments whereas HashRouter is meant for file-based environments.

Read more here:

Solution 4:

Best option at the time of this answer is to use the MemoryRouter, worked for me 🙂

Solution 5:

The (current) react-router docs say:

Generally speaking, you should use a <BrowserRouter> if you have a server that responds to requests and a <HashRouter> if you are using a static file server.

An Electron app is basically a static file server.

Related:  babel-loader jsx SyntaxError: Unexpected token [duplicate]

MemoryRouter can also work, so long as all routing originates from within the React part of the app. It only falls down when you want to navigate to a specific page from the Browser process, e.g. you want to pop up a new window and navigate directly to a “General Preferences” page. In that case, you can do this with HashRouter:

prefsWindow.loadURL(`file://${__dirname}/app/index.html#/general-prefs`);

I don’t think there is a way to do that with MemoryRouter (from the Browser process).

Solution 6:

Agree with Niekert.
But I believe it is better to handle like this before any route management.

if ( window.location.pathname.includes('index.html') ) {
    location.pathname = ROUTES.ROOT;
}

References