A quickstart guide for getting a React.js client running with a Rails API, both hosted on Heroku. Topics Covered:
- Creating a Rails API and deploying to Heroku
- Creating a React app using create-react-app and deploying to Heroku
- Configuring React app to speak to local host / Heroku instance of API automatically
This is a very quick run down so it is assumed that you have a basic understanding of Unix, Node, NPM, Rails and React. It is also assumed that you have Ruby, Node and NPM installed already.
- Heroku is platform for hosting your applications in the cloud. It is free to use withing certain limits, signing up does not require payment details to be entered.
- create-react-app is a tool created by Facebook for generating a react project from scratch quickly. It has lots of nice stuff like testing with Jest and the ability to create a 'production build'. It works by using globaly installed scripts for things like the testing and running the web-server which means that all that code doesn't need to clutter your project.
- create-react-app-buildpack is a tool that some genious invented which tells Herko how to build and deploy apps created with create-react-app
- isomorphic-fetch is a nice fetch api (for doing XmlHttpRequests and the like) that works in both node and the browser.
- @mars/heroku-js-runtime-env allows you to access environment varaibles at runtime in both Node and Heroku, we will use this to make the right api url avaialble to the client app when it is running localy and in Heroku.
- sign up to Heroku at https://www.heroku.com/
- Install & configure Heroku CLI
brew install heroku
heroku login
- follow onscreen prompts
mkdir my_react_rails_app
cd my_react_rails_app
rails new my_api --database=postgresql
cd my_api
-
Add the following to the main section of the gemfile:
gem 'rack-cors', :require => 'rack/cors'
-
bundle install
-
Add the following to config/application.rb inside the Application class decleration, ensuring to replace 'your-heroku-client-url' with the url of your own heroku client app.
config.middleware.insert_before 0, Rack::Cors do allow do origins 'http://localhost:3000', 'https://desolate-waters-78828.herokuapp.com/' #replace this url with that of your own heroku client app resource '*', :headers => :any, :methods => [:get] end end
- Create database with
rake db:create
rails s webrick -p 5000
- open new terminal tab
- Create local git repo:
git init
git add .
git commit -m "initial commit"
- Add the following to the class in app/controllers/welcome_controller.rb:
def index render json: "Welcome to the API".to_json end
- Add the following inside the do...end block in config/routes.rb:
root to: 'welcome#index'
- Commit changes:
git add .
git commit -m "adding welcome controller"
- Check the api is working by going to http://localhost:5000/ in your browser - you should see "Welcome to the API"
- Create Heroku app with
heroku create
- deploy to Heroku with
git push heroku master
- open Heroku app in your browser with
heroku open
npm i -g create-react-app
- open new terminal window in your main project directory (my_react_rails_app)
- create-react-app my_client
- Create local git repo:
git init
git add .
git commit -m "initial commit"
npm start
- Check the app is working by going to http://localhost:3000/ in your browser - you should see some sort of Welcome to React screen
- Create Heroku app with
heroku create --buildpack https://github.com/mars/create-react-app-buildpack.git
- Deploy to Heroku with
git push heroku master
- Open Heroku app in your browser with
heroku open
- Add a file called .env to the root of your project and in it add the following:
REACT_APP_API_URL=http://localhost:5000
- Add a config-variable to your heroku environment:
- Go to the settings page of your client application on heroku
- Click Reveal Config Vars
- Add a new varaible with the key 'REACT_APP_API_URL' and the value set to the url of your heroku api
npm i --save @mars/heroku-js-runtime-env
npm i --save isomorphic-fetch
- Replace the contents of src/App.js with this:
import React, { Component } from 'react'; import './App.css'; import fetch from 'isomorphic-fetch' import runtimeEnv from '@mars/heroku-js-runtime-env' class App extends Component { constructor() { super() this.state = { data: "" } } componentDidMount() { const url = runtimeEnv().REACT_APP_API_URL fetch(url) .then( res => res.json() ) .then( json => this.setState({ data: json }) ) } render() { return ( <p>Data recieved from API: { this.state.data }</p> ); } } export default App;
git add .
git commit -m "adding test API fetch"
git push heroku master
If everything went well you should now have an api and client app that will run localy and on Heroku. If not then feel free to send me a message / slack me and I will do my best to help.
🐻
Thank you very much! It really worked for me.
However, I can't get the app to work on heroku. It sound odd, but right now it's only working locally, but if I push that into heroku, it will not work.
Edit: I made steps 12 and 13 before first push, can it be the reason?