Build your first server-side rendered React app with Rails

Building any webpage with React offers many benefits like faster development time and the option to reuse components. But when you need your application to be SEO friendly, it can be a bit more difficult setting things up.

My last project was to make our new React landing page SEO friendly and keep our options open for adding features down the road. In the end I decided to follow our current stack and keep React and use Rails to allow server-side rendering of our front-end.

Great article for the benefits of using server-side rendering:

After reading many articles and lots of trial by error. I present this tutorial on building a server-side rendered landing page using React. Hopefully this tutorial will save you some time and sanity, by avoiding common problems I encountered along the way. If there is enough interest I would be happy to complete a part 2 explaining how to take this knowledge and build a simple CRUD application.

TL;DR/The code please:

Getting Setup:

Before we start you will need to install some basic pre-requisites on your machine so everything can run properly.

Pre-requisites:

RVM — install

NVM — install

BREW — install

Next run the following commands in terminal to have all the dependencies available to complete the initial setup.

rvm install 2.3.0   # For this tutorial we will use version 2.3.0 
nvm install node # Install newest version of node
gem install rails # Install newest version of Rails
gem install foreman # Install newest version of Foreman

If you have trouble setting up the environment you should read the article written by Justin.

Creating the basic landing page template:

Assuming you have all the pre-requisites installed, let’s start by creating a new Rails application.

rails new landingpage  # Feel free to use any name you wish.
cd landingpage

Now you have navigated into your fresh install of Rails its time to add React-on-rails into your Gemfile.

gem 'react_on_rails', '8.0.3'  # Add this line into your gem file.
# React-on-rails highly suggests keeping a fixed version within your # gem file as the version has to match the client/package.json
bundle install  # Run this command in terminal to use react-on-rails

Next, we will be using the React-on-rails generator to build a basic project structure. That we will rebuild into our SEO friendly React/Rails landing page.

rails generate react_on_rails:install  # Run the generator
bundle && yarn # Run bundle and yarn to prepare the application

Now let’s start the new template we have just created using:

foreman start -f Procfile.dev

This command will run your front-end and server-side application.

If everything worked properly your terminal should output something similar to mine below:

Terminal results from foreman start -f Procfile.dev

Step 1: Understand the generator

Now that you have setup your react-on-rails project using their generator lets try and understand what was created and how we can customize it to finish building our landing page.

Generated Files:

Your folder structure should be the same if not very similar to mine below. After generating the default application from react-on-rails. This structure will be the basis of your entire landing page. Below I will explain the basics of each generated file and their use within your project.

Folder structure for react-on-rails example.

Controllers: The controller will be used to send any data from your server-side to your react front-end application. For this example we are only building a landing page so this will not be used extensively and only used slightly later in this tutorial.

Views: The layout is telling Rails how to render your SCSS and JavaScript.

The folder hello_world is short and sweet but its where all the magic actually happens. The files within this folder are what you use to actually render your client side React.

Client: Within the client folder is all your front-end logic and should be slightly familiar if you have used React before.

Start rebuilding:

Now that you have a basic understanding of what was built from the generator. Lets start by renaming everything to something less “HelloWorld” and something more “IBuiltThisWithNoGeneratorGiveRaisePlease”.

Re-naming client-side:

First lets start by renaming the following folder /client/app/bundles/“HelloWorld”/ to “LandingPage”

Next you will need to edit the webpack which is located at /client/webpack.config.js, and change your path to reflect the folder name change.

entry: {
'webpack-bundle': [
'es5-shim/es5-shim',
'es5-shim/es5-sham',
'babel-polyfill',
'./app/bundles/LandingPage/startup/registration',
],
},

Since we are already in the client folder lets go ahead and change all references of HelloWorld to our new name “LandingPage”

Let’s start that by changing the generated component over to the new name at the following location. — /app/bundles/LandingPage/components/

Now change ”HelloWorld.jsx” to “Landing.jsx” and within that file change the export default class to “Landing”.

export default class Landing extends React.Component { }

Now head to the startup folder at app/bundles/LandingPage/startup and open the file “registration.jsx”. From here we will just rename every “HelloWorld” over to “LandingPage”.

import ReactOnRails from 'react-on-rails';
import LandingPage from '../components/Landing';
// This is how react_on_rails can see components in the browser.
ReactOnRails.register({
LandingPage,
});

Re-naming server-side:

Now we just have to rename all the Rails elements over to the new naming format we plan on using for our landing page.

Let’s start by editing the controllers name and the file its self. The exact file we want is located at /app/controllers/ — so now rename the file “hello_world_controller.rb” to “landing_page_controller.rb”. Within we will remove some unneeded functionality and change the names over.

# frozen_string_literal: true
class LandingPageController < ApplicationController
layout "landing_page"

def index
# This will be used later in the tutorial.
end
end

Next up, go ahead and rename all the files within the views folder located at /app/views/ . After you are done renaming everything from “hello_world” to “landing_page” head to /app/views/landing_page/. Open the file index.html.erb for editing.

Now go ahead and remove the <h1> that is located within and remove the unneeded prop since we are no longer passing one to the front-end. By default react-on-rails sets pre render to false which is the opposite of what we want for a SEO friendly landing page. Since the search engine won’t read it properly, so go ahead and set that to true.

<%= react_component("LandingPage", prerender: true) %>
# LandingPage is the name of the controller we want to use.

Last but most importantly we need to change over the routes within our Rails application. Head to /config/routes.rb and change the route to load our React landing page as the default destination.

Rails.application.routes.draw do
root 'landing_page#index'
end

Step 2: Create or integrate React components

Now that we are done the setup, its time to start getting into the real fun and start building our new landing page using React.

For this example I will be using a landing page which my team member Mackenzie Higa at Musefind volunteered. It is a stripped down version made for everyone to use.

Start out by creating the required files that we will be using during the next part of this tutorial.

Within /client/app/bundles/LandingPage/components/ create the following files.

index.jsx
Landing.jsx
LandingHeader.jsx
Footer.jsx

First open index.jsx and add the following:

export { default as Landing } from './Landing'

Next open Landing.jsx and copy/paste the following:

Landing.jsx

Now the LandingHeader.jsx:

LandingHeader.jsx

Finally, open Footer.jsx:

Footer.jsx

Once you have all four files you should have a beautiful server-side rendered React landing page. Beautiful in the context that all rendering is done server-side then sent to the client.

Server-side rendered react application.

— Maybe not so beautiful in the context of visuals but we will get to adding styling and images next.

Step 3: Getting sassy with SASS

Now that we have a basic React landing page rendering completely server-side using Rails, its time to make that landing page sexy looking.

First start by navigating to /app/assets/stylesheets/ and make application.css into application.scss. Then open that file for editing, and copy/paste the code below within that file.

Very large source-code — Click here

Perfect now on your landing page you should have server-side rendering beauty. Also actual style design-beauty thanks to Tommy Campbell who designed this landing page for us.

— Small note: you will receive some errors within the console due to retrieving fonts, but we will fix that shortly.

Step 4: Sourcing local fonts

Fonts will also be served up to our application using Rails asset pipeline since we will be calling them directly from our stylesheets.

Start by downloading the fonts we will be using if you haven’t already — Link

Now that we have these fonts installed create a new folder under /app/assets/ called “fonts” and place all fonts you just downloaded within it.

It is time to let our Rails application find these new fonts within the asset pipeline. We will do this by navigating to /config/application.rb and adding the line below within the module.

config.assets.paths << Rails.root.join("app", "assets", "fonts")

Next it is time to edit our application.scss file again and add the following to the top of the file. This will import the fonts so we can use them within our stylesheets.

If you followed every step until now, you should have a perfect working landing page. Except for the social media icons located on the footer.

Step 5: How to source images

When I was trying to complete this step, it ended up being a couple hours of self hatred and anger. Which in the end turned into just uploading my images to Cloudinary and linking them externally. A solution I was personally happy to push live although for the sake of this tutorial I decided to hunker down and figure it.

So without further ado I present you the work-around I put in place with about five minutes of googling on the second time around.

First if you have not already download and place the following images within /app/assets/images/

Once you have the assets placed within the proper folder its time to navigate and open /app/controllers/landing_page_controller.erb . It’s finally time that we add something within this controller like I promised at the start of this tutorial.

class LandingPageController < ApplicationController
layout "landing_page"

def index
@images = {
instagram: path_to_asset('landing/server-instagram'),
twitter: path_to_asset('landing/server-twitter'),
medium: path_to_asset('landing/server-medium')
}
end

private
def path_to_asset(asset)
ApplicationController.helpers.asset_path(asset)
end
end

We are creating a prop of images to pass from the back-end to the front-end of our application. We can’t just locally source images from our front-end since Rails will overwrite any path you try and enter including images.

Now that we have created an object of images that have our Rails assets pipeline routes we will need to pass this information to the front-end. We will do this by editing /app/views/landing_page/index.html.erb

<%= react_component("LandingPage", props: @images, prerender: true) %>

Here we are simply passing a prop to the front-end which contains all the paths for the images we need access to.

Full render of landing page

Conclusion

At this point you have a fully working landing page built with React. and rendered server-side using Rails, to create a SEO friendly application. Hopefully it has given you an idea on how to continue with this knowledge and build or convert an application into a SEO friendly power house.

If you wanted to deploy your application on Heroku I have listed an external source below which I have not personally tested:

If this article has been helpful in anyway please click the green heart below. If you are feeling very generous, feel free to share it to your inner circle so you can virtually brag about your newly learned knowledge.

Thanks for reading.

Git repo: