0
votes

I have a Rails API application and a separate standalone React application.

I want to create a controller that returns this whole app to the end user and let the react app consume the API from the dedicated controllers, instead of creating two servers.

How can I do this neatly?

The react app tree is:

  • public
    • favicon.ico
    • index.html
    • manifest.json
  • src
    • Assets/
    • Componenets/
    • Views/
    • App.css
    • App.js
    • index.css
    • index.js
    • registerServiceWorkder.js
  • README
  • package.josn
  • package-lock.json
2
You probably want to bundle the JS in the asset pipeline. There are tutorials on how to do this. - Max
Set this up in your routes. The root path should deliver the client-side app. The rest can be the API. - tadman

2 Answers

2
votes

Not very experienced on this matter, but if it would help, this is what I did in my recent project:

  • Use / integrate webpacker gem into your Rails project

  • app/config/routes.rb:

    # all JSON requests goes here
    scope constraints: -> (request) { request.format == :json } do
      # all of your Rails API routes goes here
    end
    
    # all HTML requests goes here,
    # as your react-router should already be able to handle this
    scope constraints: -> (request) { request.format == :html } do
      # this matches ALL paths to bootstrapper action
      match '*path', to: 'application#bootstrapper'
    end
    
    root 'application#boostrapper'
    
  • app/controllers/application_controller.rb:

    def bootstrapper
      render template: 'layouts/bootstrapper'
    end
    
  • app/views/layouts/bootstrapper.html.erb

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!-- YOUR USUAL <head> HERE -->
        <%= stylesheet_link_tag    "application" %>
        <%= javascript_include_tag "application" %>
        <%= csrf_meta_tags %>
      </head>
      <body>
        <!-- DONT NEED THE <%= yield %> HERE -->
        <%= javascript_pack_tag 'your_react_pack' %>
        <%= stylesheet_pack_tag 'your_react_pack' %>
      </body>
    </html>
    
  • Finally configure your app/javascript/packs/your_react_pack.js (This is the entry-point of your React files, and so you'll import your React app here) See webpacker for details

Bonus

  • Cross-Site Request Forgery (CSRF) protection is a must! In Rails 5 (or perhaps 4 as well?) you can simply use Rails.csrfToken() to get the token in JS, and pass it as a 'X-CSRF-Token' header when submitting JSON requests to your Rails app. Make sure you have //= require rails-ujs in your app/assets/javascripts/application.js for you to be able to use Rails.csrfToken()
0
votes

I can't give you a direct write up of how to connect them, it would be a bit lengthy but here is a link that can get you on your way:

  1. This link talks about 'create-react-app' which is what you did to create your react application and Rails API.

https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/

In general, all you do is create 'Rails API' application and render json with your controllers and use React fetch/axios to connect to the your Rails API