How to Deploy a JavaScript-Rails App on Heroku and GitHub Pages
Tags: javascript, rails, heroku, github
Published: 2020-04-29 15:39:42

For a codenewbie like myself, sometimes the seemingly-simple procedural tasks like setting up environments and deploying apps can seem way more complicated than creating amazing applications from scratch. After a lot of trial and error and reading multiple articles with complicated configurations, I wanted to share this simple procedure for deploying a JavaScript app with a Rails API backend.

*Disclaimer: The intended purpose of deploying this particular app is just to share and test my project on the web for free. If you are deploying an app for true production, I would recommend a more comprehensive hosting solution.*

###The Challenge
I created [Watershed Monitor](https://dev.to/jessesbyers/watershed-monitor-javascript-and-rails-project-576c) a few months back, and initially tried to deploy it using Heroku as I had for my Rails app. I immediately ran into a number of issues. I quickly realized my application was actually TWO stand-alone applications, including a Rails API backend with a Postgres Database, and a simple JavaScript frontend (single-page application built upon an index.html file). 

###File Structure
Unfortunately, I had built and saved them in a single repository, which was structured like this:

![Imgur](https://i.imgur.com/0EM0uyI.png)

I had created the backend folder using the `rails new` command, and had manually created the frontend folder with frontend files including the index.html file, a styles.css file, and an src folder including three javascript files. Before doing anything related to deployment, I branched the repo so that I could easily revert to a previous version in case something went wrong.

##Deploying the Backend Folder to Heroku
To deploy the Rails app, I used the following commands from the command line, in the root directory of the application.

1. Log into Heroku from the command line, and follow the prompts:
`heroku login`

2. Initiate the new repository for Heroku deployment:
`git init`

3. Create and name the Heroku repository. I recommend tagging "-api" to the name so you know it is an api.
`heroku create NAME_OF_APP_API`

4. Add and commit your changes:
`git add .`
`git commit -m "first commit"`

5. Push your commit to Heroku master. This will be done in different ways depending on your file structure:

*If your Rails API is in its own standalone repository:*
`git push heroku master`

*If your Rails API is in a folder within the root directory (as mine is):*
`git push --force heroku 'git subtree split --prefix NAME_OF_BACKEND_FOLDER HEAD':master`

This command splits the Rails API backend directory from the rest of the repository, and pushes just that sub-tree to Heroku for deployment.

Next, open your API using the command line, or navigate to the Heroku url that is provided to you:
`heroku open`

###Resetting the Postgres Database

At this point, you technically have a Heroku app up and running, but you likely will not see any data if you navigate to the site. You will first need to reset your database.

1. Create the Database:
`heroku rake db:schema:load` (Note: you may be able to use `heroku rake db:create`, but this caused errors for me)

2. Run the Migrations and Re-seed the Database (if applicable)
`heroku rake db:migrate`
`heroku rake db:seed`

###Commit and Re-push the Changes to Heroku
Anytime you make changes after the initial deployment, the following commands will save and push the new updates to your deployed app.

`git add .`
`git commit -m "new commit message"`

Use the same git push command you originally used:
`git push heroku master` 
OR 
`git push --force heroku 'git subtree split --prefix NAME_OF_BACKEND_FOLDER HEAD':master`

###Check the Browser
Use 'heroku open' to check that your json data is appearing correctly in the browser. Mine looked like this:
![Imgur](https://i.imgur.com/BeNu88b.png)

*Important Note: If you did not set a root route in your config/routes.rb file, you may see this error message, and that is fine! You could fix this by setting a dummy root route in config/routes.rb. However, if you navigate to an index or show page that is defined in your routes, you should be able to see your data, and the application will still work.*
![Imgur](https://i.imgur.com/26Aszry.png)

##Deploying the Frontend Using GitHub Pages
First, give yourself a pat on the back, because you just finished the hardest part! To deploy the front end, after a small amount of setup, you can just enable GitHub Pages to display your index.html file.

###Revise the Fetch URLs in the Frontend Files
You likely have a number of functions in your application that fetch data from your API, and all of those will need to be changed to match the Heroku URLs. In my case, I had already defined a constant for my backend URL, so I only needed to update one URL, changing it from localhost:3000 to my new URL below:

```
     // ******************VARIABLES***********************
    // const BACKEND_URL = "http://localhost:3000"
    const BACKEND_URL = "https://watershed-monitor-api.herokuapp.com/"
```

If you did not set your URL as a constant, you would need to search for and change every instance of the URL (and then remember to set a constant in your next app). Now is a great time to test the app and make sure everything is still working before you commit changes to your GitHub repository.

###Enabling Github Pages
Finally, the magic happens! At this point, all you need to do is update the settings in your GitHub repository to display your site. The process is described in the [documentation](https://pages.github.com/), and you can skip ahead to their Step 4 since you already have your app created.

1. Click on the Settings tab and scroll to GitHub Pages (at the bottom).

2. Choose a branch that you want to deploy (most likely Master).

3. Navigate to the URL following this pattern:
` http://username.github.io/repository`

*Important Note: If your frontend and backend are saved in the same repository, you will need to change the URL accordingly to access your index.html site.*

When I navigated to `https://jessesbyers.github.io/watershed-monitor`, all I saw was my readme file. But after drilling down into my frontend folder, the site displayed and functioned just as I had hoped:
`https://jessesbyers.github.io/watershed-monitor/watershed-monitor-frontend/`
![Imgur](https://i.imgur.com/aWcZyTg.png)

I hope this helps you get your JavaScript-Rails applications up and running with minimal frustration...but if something isn't working, or you've found other approaches that work well for you, drop a note in the comments!