How to convert a Rails (erb) view to React (jsx)

I’m rebuilding the front end of a Rails 5 project as a single page app in React. Here’s my “quick and dirty” search and replace approach to jump-starting the process.


HTML comments need to be converted to JavaScript comments.

Search: <!--
Replace: {/*

Search: -->
Replace: */}

ERB Tags

The dynamic content that was previously generated by Ruby/Rails will need to be manually refactored so that it is handled by your React component(s). This is where most of the work will happen. To make this more straight-forward, I converted the ERB tags to instead output strings so it was easy to see where I needed to refactor.

Search: <%=
Replace: {'

Search: <%

Search: %>
Replace: '}

After this, you will see things like in the rendered HTML. It’s ugly, but that’s the point. It needs to get replaced anyway, so might as well make it obvious what should eventually go there.

Class and for Attributes

There’s a couple HTML attributes that collide with reserved keywords in JavaScript, so we’ll need to update those too. Notice the leading spaces. This is helpful to prevent unintended consequences. Also, to be even safer I included the = in the search/replace term, but if your code has spaces around the =, you’ll need to make adjustments.

Search: class=
Replace: className=

Search: for=
Replace: htmlFor=

A gotcha

I started by copy/pasting my layout file from Rails into the public/index.html file provided by create-react-app. I replaced the Rails yield with <div id="root"></div>. Then I copy/pasted the entire view file into the render function in src/App.js.

The plan was to leave the legacy code in index.html as static HTML while breaking down all the dynamic content in the App component into more granular components. This is fine, but if there are ERB tags, etc in the index.html file then webpack will probably error out. I don’t know exactly what’s going on under the hood, but I had to remove all the ERB tags from index.html also before webpack could successfully compile the bundle. This isn’t hard to do, but the errors might not be very helpful or clear about what is going on. I spent a couple hours debugging the JSX in App.js before I figured out that the source of the problem was a different file.