0

I am attempting to serve a react app from the public folder of my rails app. I am building the js file and putting it in the public folder. When I go to the root of the app, I can see that the js and my index.html page have loaded. However, when I try to go to page, like /landing, I get a 404, route not found from Rails. I can't figure out why the react router is not kicking in. This all works on dev where I am serving the react app with a second server, I only get this issue in production. Any suggestions?

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.scss';
ReactDOM.render(<App />, document.getElementById('root'));

App.js

import React from 'react';
import Auth from './util/auth';
import { Redirect, BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import MyAccount from './components/my_account';
import MyListings from './components/my_listings';
import LoginPage from './components/login_page';
import LandingPage from './components/landing_page';
import RegistrationForm from './components/registration_form';
import PasswordResetForm from './components/password_reset_form';
import RequestPasswordResetForm from './components/request_password_reset_form';
import {FlashMessages} from './components/flash_messages';

import $ from 'jquery';
import popper from 'popper.js';
import './stylesheets/App.css';
window.Popper = popper;
window.jQuery = $;
window.$ = $;
global.jQuery = $;
require('bootstrap');

const App = appProps => (
  <div>
    <div id="flash-messages">
      <FlashMessages />
    </div>
    <Router>
      <div className="App">
        <Switch>
          <Route exact name="index" path="/landing" component={LandingPage} />
          <Route exact name="login" path="/login" component={LoginPage} />
          <Route exact name="register" path="/register" component={RegistrationForm} />
          <Route exact name="reset_password" path="/reset_password" component={PasswordResetForm} />
          <Route exact name="reset_password_request" path="/reset_password_request" component={RequestPasswordResetForm} />
          <PrivateRoute path="/my_account" component={MyAccount}/>
          <PrivateRoute path="/my_listings" component={MyListings}/>
        </Switch>
      </div>
    </Router>
  </div>
);

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    Auth.isAuthenticated() ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)
export default App;

3 Answers 3

0

A typical gotcha with React Router is that you need to return the same index.html page for all routes - be it /, /landing-page/ or /a/really/deep/route/.

You typically solve that by adding a catch-all route. I don't know rails all that well, but I think this answer might help you out.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is that all routes handled first by rails and he redirects you to the page where your react routers are. And you have only one HTML page that contains your react.js code. When you go to /login or any other page you get err 404 because you don't have a route in rails to handle it. You need to add rails routes for all your pages and redirect them to the same index page Or do a catch all routes to the same index page

Comments

0

There's some documentation for configuring your server. Basically you always need to return index.html with a 200 status code.

https://github.com/ReactTraining/react-router/blob/v3/docs/guides/Histories.md#configuring-your-server

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.