How to use React Router with Electron?

JavascriptReactjsReact RouterElectron

Javascript Problem Overview


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:

<script src="http://localhost:3000/dist/bundle.js"></script>

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?

Javascript Solutions


Solution 1 - Javascript

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 2 - Javascript

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?

Solution 3 - Javascript

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 4 - Javascript

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

Solution 5 - Javascript

What about simply using Switch to default to "/" as follows:

<Switch>
  <Route path="/" exact component={Home}/>
  <Route path="/foo" component={Foo}/>
  <Route path="/bar" component={Bar}/>
  <Route render={() => <Redirect to="/"/>}/>
</Switch>

This way, "/index.html" will redirect to "/"

Solution 6 - Javascript

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.

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

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;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFrozen CrayonView Question on Stackoverflow
Solution 1 - JavascriptJoshua PinterView Answer on Stackoverflow
Solution 2 - JavascriptaestrroView Answer on Stackoverflow
Solution 3 - JavascriptNiekertView Answer on Stackoverflow
Solution 4 - JavascriptGabriel MatusevichView Answer on Stackoverflow
Solution 5 - JavascriptChisholmKyleView Answer on Stackoverflow
Solution 6 - JavascriptJ. PerkinsView Answer on Stackoverflow
Solution 7 - JavascriptArseniy-IIView Answer on Stackoverflow