React on Rails Basic Tutorial
This tutorial guides you through setting up a new or existing Rails app with React on Rails, demonstrating Rails + React + Redux + Server Rendering. It is updated to 11.2.1.
After finishing this tutorial you will get an application that can do the following (live on Heroku):
You can find here:
By the time you read this, the latest may have changed. Be sure to check the versions here:
Note: some of the screen images below show the "npm" command. react_on_rails 6.6.0 and greater uses yarn
.
Setting up the environment
Trying out React on Rails is super easy, so long as you have the basic prerequisites. This includes the basics for Rails 5.x and node version 6+. I recommend rvm
and nvm
to install Ruby and Node, and brew to install yarn. Rails can be installed as an ordinary gem.
nvm install node # download and install latest stable Node
nvm alias default node # make it default version
nvm list # check
brew install yarn # you can use other installer if desired
11\.\d+\.\d+
rvm install 2.5.0 # download and install latest stable Ruby (update to exact version)
rvm use 2.5.0 --default # use it and make it default
rvm list # check
gem install rails # download and install latest stable Rails
gem install foreman # download and install Foreman
Then we need to create a fresh Rails application with webpacker react support as following.
First be sure to run rails -v
and check you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install webpacker with react per the instructions here.
cd <directory where you want to create your new Rails app>
# any name you like for the rails app
rails new test-react-on-rails --webpack=react
cd test-react-on-rails
bundle
Note: if you are installing React On Rails in an existing app or an app that uses Rails pre 5.1.3 (not for Rails > 5.2), you will need to run these two commands as well:
bundle exec rails webpacker:install
bundle exec rails webpacker:install:react
Add the React On Rails gem to your Gemfile
:
gem 'react_on_rails', '11.2.1' # prefer exact gem version to match npm version
Note: Latest released React On Rails version is considered stable. Please use the latest version to ensure you get all the security patches and the best support.
Run bundle
and commit the git repository (or rails generate
will not work properly)
bundle
# Here are git commands to make a new git repo and commit everything.
# Newer versions of Rails create the git repo by default.
git add -A
git commit -m "Initial commit"
Install React on Rails: rails generate react_on_rails:install
or rails generate react_on_rails:install --redux
. You need to first git commit your files before running the generator, or else it will generate an error.
rails generate react_on_rails:install
bundle && yarn
Then run server with static client side files:
foreman start -f Procfile.dev
To run with the webpack-dev-server:
foreman start -f Procfile.dev-server
Visit http://localhost:3000/hello_world and see your React On Rails app running! Note, foreman defaults to PORT 5000 unless you set the value of PORT in your environment or in the Procfile.
Using a pre-release of rails/webpacker
Until rails/webpacker
v4 ships, or if you ever want to try out the master branch, you can modify the React on Rails tutorial instructions slightly. You can see the sequence of commits here. To summarize:
Don't run rails new
with the --webpack=react
option. Instead, add the webpacker gem to the Gemfile such that it points to master, like this if 11.2.1
is the version you want.
gem 'webpacker', github: "rails/webpacker"
gem 'react_on_rails', '11.2.1' # always use exact version
Then run these commands:
bundle exec rails webpacker:install
yarn add "rails/webpacker" # because the installer has a bug that puts in an invalid version in your package.json.
bundle exec rails webpacker:install:react
yarn add --dev webpack-dev-server
run rails generate react_on_rails:install && bundle && yarn
Custom IP & PORT setup (Cloud9 example)
In case you are running some custom setup with different IP or PORT you should also edit Procfile.dev. For example to be able to run on free Cloud9 IDE we are putting IP 0.0.0.0 and PORT 8080. The default generated file Procfile.dev
uses -p 3000
.
web: rails s -p 8080 -b 0.0.0.0
Then visit https://your-shared-addr.c9users.io:8080/hello_world
RubyMine
It's super important to exclude certain directories from RubyMine or else it will slow to a crawl as it tries to parse all the npm files.
- Generated files, per the settings in your
config/webpacker.yml
, which default topublic/packs
andpublic/packs-test
node_modules
Deploying to Heroku
Create Your Heroku App
Assuming you can login to heroku.com and have logged into to your shell for heroku.
- Visit https://dashboard.heroku.com/new and create an app, say named
my-name-react-on-rails
:
Run this command that looks like this from your new heroku app
heroku git:remote -a my-name-react-on-rails
Set heroku to use multiple buildpacks:
heroku buildpacks:set heroku/ruby
heroku buildpacks:add --index 1 heroku/nodejs
Swap out sqlite for postgres by doing the following:
- Delete the line with
sqlite
and replace it with:
gem 'pg'
- Run
bundle
- Replace your
database.yml
file with this (assuming your app name is "ror").
default: &default
adapter: postgresql
username:
password:
host: localhost
development:
<<: *default
database: ror_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: ror_test
production:
<<: *default
database: ror_production
Then you need to setup postgres so you can run locally:
bundle
rake db:setup
rake db:migrate
I'd recommend adding this line to the top of your routes.rb
. That way, your root page will go to the Hello World page for React On Rails.
root "hello_world#index"
Next, configure your app for Puma, per the instructions on Heroku.
Create /Procfile
. This is what Heroku uses to start your app.
Procfile
web: bundle exec puma -C config/puma.rb
Note, newer versions of Rails create this file automatically. However, the docs on Heroku have something a bit different, so please make it conform to those docs. As of 2018-10-13, the docs looked like this:
config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
Then after all changes are done don't forget to commit them with git and finally you can push your app to Heroku!
git add -A
git commit -m "Changes for Heroku"
git push heroku master
Then run:
heroku open
and you will see your live app and you can share this URL with your friends. Congrats!
Turning on Server Rendering
You can turn on server rendering by simply changing the prerender
option to true
:
<%= react_component("HelloWorld", props: @hello_world_props, prerender: true) %>
Then push to Heroku:
git add -A
git commit -m "Enable server rendering"
git push heroku master
When you look at the source code for the page (right click, view source in Chrome), you can see the difference between non-server rendering, where your DIV containing your React looks like this:
<div id="HelloWorld-react-component-b7ae1dc6-396c-411d-886a-269633b3f604"></div>
versus with server rendering:
<div id="HelloWorld-react-component-d846ce53-3b82-4c4a-8f32-ffc347c8444a"><div data-reactroot=""><h3>Hello, <!-- -->Stranger<!-- -->!</h3><hr/><form><label for="name">Say hello to:</label><input type="text" id="name" value="Stranger"/></form></div></div>
For more details on server rendering, see:
Moving from the Rails default /app/javascript
to the recommended /client
structure
ShakaCode recommends that you use /client
for your client side app. This way a non-Rails, front-end developer can be at home just by opening up the /client
directory.
- Move the directory:
mv app/javascript client
- Edit your
/config/webpacker.yml
file. Change thedefault/source_path
:
source_path: client
Using HMR with the rails/webpacker setup
Start the app using foreman start -f Procfile.dev-server
.
When you change a JSX file and save, the browser will automatically refresh!
So you get some basics from HMR with no code changes. If you want to go further, take a look at these links:
- https://github.com/rails/webpacker/blob/master/docs/webpack-dev-server.md
- https://webpack.js.org/configuration/dev-server/
- https://webpack.js.org/concepts/hot-module-replacement/
- https://gaearon.github.io/react-hot-loader/getstarted/
- https://github.com/gaearon/react-hot-loader
React on Rails will automatically handle disabling server rendering if there is only one bundle file created by the Webpack development server by rails/webpacker.
Conclusion
- Browse the docs either on the gitbook or in the docs directory on github
Feedback is greatly appreciated! As are stars on github!
If you want personalized help, don't hesitate to get in touch with us at [email protected]. We offer React on Rails Pro and consulting so you can focus on your app and not on how to make Webpack plus Rails work optimally.