React Routing works in local machine but not Heroku React Routing works in local machine but not Heroku javascript javascript

React Routing works in local machine but not Heroku


I actually came across this post first before 3 hours of searching through react-router and heroku documentation. For swyx, and anyone else having the same problem, I'll outline the minimum of what you need to do to get this working.

router.js - (Obviously change AppSplash and AppDemo to your components)

export default <Router history={hashHistory}>  <Route path="/" component={App}>    <IndexRoute component={AppSplash}/>    <Route path="demo" component={AppDemo}/>  </Route></Router>

app.js

import React, { Component } from 'react'class App extends Component {static propTypes = {  children: PropTypes.node}render() {  const { children } = this.props  return (    <div>      {children}    </div>  )}}export default App

Create a new file in the root of your home directory and name it static.json. Put this into it.

{  "root": "build/",  "clean_urls": false,  "routes": {    "/**": "index.html"  }}

Push to heroku again. The routes should work this time.

Explanation:

You need to modify Heroku's default webpack, otherwise the service gets confused with how to handle the client-side routing. Essentially what static.json does. The rest is just the correct way to handle the routing according to the 'react-router' documentation.


How to fix client-side routing errors (Heroku 404 errors):

React Browser Router

If you're using React Browser Router, as an npm module with create-react-app, then the solution (which works for me) is to create a static.json file (within the same directory as package.json).

{  "root": "build/",  "clean_urls": false,  "routes": {    "/**": "index.html"  }}

Here is why this solution works:

Create-react-app is for the most part a Node.Js server which serves client-side React. The public static directory is mapped to the / endpoint, and visiting this endpoint from a browser will download the index.html webpage. This webpage in turn loads the React components. And because React Browser Router is a React component, the routes are loaded dynamically after visiting the / endpoint. In other words, before the index.html webpage is loaded all our React Browser Router routes will result in 404 errors on Heroku. To resolve this issue, a static.json file can be used to map any endpoints with the following pattern /** to the index.html file, which in turn will load React Browser Router and correctly load the react components for that route.

From an Apache HTTP server:

Likewise, on an Apache HTTP server creating an .htaccess file in the public directory, will remap all endpoints that match /** to the index.html file.

Options -MultiViewsRewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^ index.html [QSA,L]

More resources

Also read the "Deployment" section of the create-react-app README, which has a ton of good information on how to reconfigure the server to use client-side routing.

https://facebook.github.io/create-react-app/docs/deployment

React Static Router

Lastly, React Router offers a static router, React Static Router, which can be used with the "react-dom/server" npm module on a Node.js server, to render JSX server-side, and doesn't need static.json or .htaccess reconfiguration.


Try this:

app.get("*", (req, res) => {  let url = path.join(__dirname, '../client/build', 'index.html');  if (!url.startsWith('/app/')) // since we're on local windows    url = url.substring(1);  res.sendFile(url);});

Worked for me when I put into server.js.