Create a Rails app with React for frontend using Esbuild and Jsbundle
Tags: react, ruby, rails, esbuild
Published: 2022-11-18 13:15:36

This post explains how I use esbuild and jsbundling to integrate a Rails 7 application with React.js as the frontend.
I use esbuild as my JavaScript bundler, but you may also use Webpack or rollup.js.
I'll describe the steps I followed, as well as the bugs I encountered and how I fixed them.
I'll be using the following versions: Ruby 3.1.2, Rails 7.0.4, and React 18.2.0 for this setup.

### Step 1
I created a new rails app called reactapp and included j and esbuild flags.

```
rails new reactapp -j esbuild

``` 

Then I run the following code to launch Rails server.

```
run rails server

``` 
### Step 2
You can see the commands for simultaneously running the JavaScript files and the Rails server in your Procfile.dev  file.

```
// To run rails server and Javascript files simultaneously

web: bin/rails server -p 3000

```
But you may also use the following codes to run them independently on different terminals.

```
// To run only Javascript files
 
yarn build --watch

```
and 

 ```
//To run only rails server

rails server

```
### Step 3
After running my rails server and JavaScript files, I encountered a bug as shown below.

![Server Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4za00kber2wv6akhxnf8.PNG)
To debug the error I changed my package.json file as shown below

![Solution to server error above](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0miju1hegpj6zx37wo6c.PNG)
Note that you may probably not encounter this bug.

### Step 4

I utilize stimulus to create a controller for my react setup by executing the code below since stimulus have been added to the Gemfile during initial setup in step 1 above.

```
rails g stimulus react

```
The react controller.js file was generated by running the code above.

### Step 5

The newly created react_controller.js file is as shown below

```
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="react"
export default class extends Controller {
  connect() {
  }
}
```
### Step 6

Now I run the code below to create my home page.

```
rails g controller pages home

```

![Creating home page code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zyonud1o764qcx3p6wl.PNG)


### Step 7

In the **routes.rb** file, I added the below code to create my home page route.

```
root 'pages#home'

```
My routes.rb file is now as displayed below.

![routes.rb file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0pvhht9rcfvai9lwq36.PNG)

### Step 8

In the **home.html.erb** file I added the following code

 ``` 
  <%= content_tag(:div, "",
 id:"app", data: {
 	controller: "react"
 })%>

```

Now the **home.html.erb** file is as seen below

![home.html.erb file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ue38a7acyct1z22in7r.PNG)

Keep in mind that the name of your controller should match the name of the stimulus you created in step 4 above.

### Step 9
In the react_controller.js file I console log "react controller connected" to test if my JavaScript files are connecting with my rails application


![react_controller.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3z3mn1vstmtuab8xwphy.PNG)

At this point, You may encounter an error when you run rails server as I did below,

![encountered error when run rails server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7npzi67slxkwfvk2es2.PNG)

Run Rails Server from your Windows command prompt to fix the aforementioned error. For me, it fixed the issue as shown below.

![solved error ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t923kv3wnzktngt3buvq.PNG)

From the console you can see "react controller connected" indicating that JavaScript is running and connecting to rails. 

### Step 10
Let's now add some react components. First, I ran the code below to add react and react-dom packages to the application.

```
yarn add react react-dom
```
In the package.json file, you can see react and react-dom have been included.


![The package.json file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrqkwxu2xtrobgjab4y4.PNG)

### Step 11

Now I created App.js file in app/javascript/controllers folder
as seen below.

![The App.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sh5nbbntrrlkbq4avz3a.PNG)

### Step 12 
In the **react_controller.js** file I imported App.js, react and react-dom and then added the following code below

```
 const root = ReactDOM.createRoot(document.getElementById("app"))
     root.render(
      <App/> 
     )
```
Now the **App.js** file is as seen below.

![The App.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0m4tlrfngqqhw9819ov.PNG)

### Step 13

When I ran my JavaScript file using the code in step 2 above, I got the error you can see below after creating the App.js file.

![Error after creating App.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fhheaydzan5b6uehho3.PNG)

To solve the above error I added "--loader:.js=jsx" to the package.json script as seen below


![the package.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xickqn40l9x8f9ft5t25.PNG)

My App.js file is now rendered in the browser as shown below.

![App.js file rendered on the browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xd6sa4h9of5vae91gf3y.PNG)

### Step 14
Let's create two components . First, I added react-router-dom package to the application and  then create the clock.js and count.js components as seen in the images below

```
yarn add react-router-dom
``` 
![count component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q81uzk8ai6iljhoyfv39.PNG)


![clock component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saber3yljg2gcscjvgf3.PNG)

### Step 15
In the **App.js** file I imported clock.js, count.js and react-router-dom. As seen below.


![App.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eyxx72a9nw1o0bf718ov.PNG)



### Step 16
To create routes for the two newly created components, I added the following code to the routes.rb file.

```
get '*path', to: 'pages#home', via: :all 
```
As seen below, my two components have now been rendered and are viewable in the browser.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4xrwr05sh0qsxs24owz.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4zozj7gbwjayimywi16.PNG)

### Step 17
 Now I used react hooks for state update and useEffect for side effects. As seen below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/040ljpq4gf56e6i71o7j.PNG)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d57xy7norq2u48ws5h5s.PNG)


In conclusion, I've provided the GitHub repository for the tutorial I described above, on [how I used esbuild and Jsbundle to connect rails and React](https://github.com/Mekarosi/reactapp) . I hope this tutorial will be useful to someone. Thanks for reading.