29

Now i am making React app on top off Ruby on Rails app (with out react-rails gem) by using browserify-rails to compile js files.

So i tried to us react-router to config router of the app

This is my main.js

import React from 'react';
import ReactDOM  from 'react-dom';
import { Router, Route } from 'react-router';
import { browserHistory } from 'react-router';

/*Import Component*/

import DashBoard from './components/dashboard';
import Group from './components/dashboard';

/*
 *
 * Routes
 *
 * */

var routes = (
    <Router history={browserHistory}>
        <Route path="/" component={DashBoard}/>
        <Route path="/group" component={Group}/>
    </Router>
);

ReactDOM.render(routes , document.querySelector('#main'));

But when i go to

http://my.app.dev/group

I got

No route matches [GET] "/group" (From Rails)

So how can i fix this and make React Router on top off Rails router?

Thanks!

3 Answers 3

55

If you want to redirect all your request to single page, that's easy:

# config/routes.rb 

root 'dash_board#index'
get '*path', to: 'dash_board#index'

If Rails will render your React components on DashBoard#index page, React's router will intercept it from there.

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

9 Comments

Is this a good practice? Do you then make all actions non-html and handle all routing in react? Just trying to learn the purpose of react routing, thanks!
Having a "first level" wildcard route can deal to problems with some gems. What you could do is to mount your app, for instance in a namespace. For instance: yourdomain/a . It is uglier but safer.
But what happens to API routes? How we will be able to call API if we force all request to go to one particular page?
@KrupaSuthar Good question. Rails routes matches top down, so if you put the *path at the very end of your file the API endpoints will remain untouched.
This approach has a problem when you are dealing with URL generated when retrieving files from ActiveStorage. I get a 406 error (Not Acceptable). It seems that ActiveStorage is not taking control of this route anymore after the addition of the solution proposed here.
|
1

You can also specify all the URLs you need in Router, manually in routes.rb, redirecting them to your rails controller with the Router, say /home:

# config/routes.rb 
Rails.application.routes.draw do
  root action: :index, controller: 'home'

  get 'url1', action: :index, controller: 'home'
  get 'url2', action: :index, controller: 'home'
  get 'url3', action: :index, controller: 'home'
end

Note that your base React component will use Router to use the corresponding component, if you have something like:

<Route path="/url1" component={ ComponentForUrl1 } />
<Route path="/url2" component={ ComponentForUrl3 } />
<Route path="/url3" component={ ComponentForUrl2 } />

1 Comment

This still first sent the request to the rails router and then back to the react-router. Thus unloading the Root component.
1

It might be 2 years later, but I believe I'm not the only one having this issue nowadays, so here's un updated answer that actually helped.

Instead of only defining a redirect from *path, to a desired route, a constraints parameter must be provided so requests for resources (css, js, etc.) don't get 406 responses:

get '*path', to: "home#index", constraints: ->(request) do
  !request.xhr? && request.format.html?
end

I found the solution here.

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.