This is the second part of our series on building a Rails 5.2 application with webpack and react powered frontend, and here are some of the things we'll cover:
Overview of Part 1
- Completely remove and bypass the asset pipeline (sprockets)
- Exclude turbolinks
- Use webpacker to handle stylesheets and all other assets
- Add user auth using Devise
- Structure and organize our views
- Structure and organize JS and assets
- Add Blueprint.js library
- Set up public application
- Build a simple user dashboard
We've created a reference app to follow along with the guide here: https://github.com/devato/rails-webpacker-react/tree/part-2
Add user auth
There are detailed instructions on how to setup devise here: https://github.com/plataformatec/devise#getting-started
Add devise to the gemfile and
gem 'devise', "~> 4.5"
Generate devise files:
$ rails generate devise:install
Add the user model via devise:
$ rails generate devise User
$ rails db:migrate
Setup public views
We're going to have two separate layouts
applicationwill be for the home page and devise views
- A separate
applayout will be used for the dashboard.
This will allow us to use the full Rails stack with views for public pages, and then have our Dashboard a full SPA using React.
Let's start by adding some links to get around the app:
Add the following above the
<%= link_to 'Homepage', root_path %>
And replace the contents with this snippet to start creating a functional app:
<h1>Home</h1> <ul> <% if user_signed_in? %> <li><%= link_to('Logout', destroy_user_session_path, method: :delete) %></li> <% else %> <li><%= link_to('Login', new_user_session_path) %></li> <li><%= link_to('Register', new_user_registration_path) %></li> <% end %> </ul>
This will allow us to navigate around the application but we're not concerned with the awful styling just yet.
Setup the dashboard layout
Like I said we're going to create a separate layout for the dashboard so it can be entirely handled by react.
Generate a new controller for it:
$ rails g controller app/dashboard index
Now, open the newly generated controller and set it's layout:
Create new layout
app/views/layouts/app.html.erb with the following content:
applicationwill be used for publicly accessible pages, like the homepage, and devise views.
appwill be used for the internal authed dashboard.
Now that our views are all ready, let's organize our JS and assets in the frontend directory.
We're going to have isolate public/private assets under parent
frontend directories to help with organization. Let's set up our frontend directories like this:
frontend |-- app | |-- assets | | |-- images | | |-- styles | |-- components |-- application | |-- assets | | |-- images | | |-- styles | |-- components |-- packs | |-- app.js | |-- application.js
This will give us a solid structure to keep our frontend organized and easy to reason about, and will also keep assets for
application separate from
Blueprint.js is a collection of powerful React components. We opted to use this library to reduce the load of developing custom components.
Let's start by adding the core library using yarn:
$ yarn add @blueprintjs/core react react-dom
Stylesheets will be imported in the entrypoint, pack files for
Set up public Application
Our public application is going to work differently than the private dashboard which only authed users will have access to.
Start by adding the yarn package
rails-ujs which provides many features to Rails like non-GET requests, submitting form via ajax and other things.
$ yarn add rails-ujs
Let's also create a custom
app/frontend/application/assets/styles/application-styles.scss to handle custom styles we'll add later.
app/frontend/packs/application.js and replace it's content with this:
import '@blueprintjs/icons/lib/css/blueprint-icons.css' import '@blueprintjs/core/lib/css/blueprint.css' import '../application/assets/styles/application-styles' import Rails from 'rails-ujs' Rails.start(); console.log('Application Pack')
This imports css from blueprint styles, imports our custom
application-styles, runs Rails.start() to handle rails-ujs and logs which pack we're running.
Webpacker will automatically generate an
application.css file for us based on these imports, and we just need to reference it in the
<%= stylesheet_pack_tag 'application' %>
After the page reloads, you should see the new styles take affect,
Application Pack should be logged to the console and with this in place, we're done with the application section. You can register, and click around to see if everything is working as expected.
Take a break
You've earned it. Even With everything we just accomplished our app is still very basic, but is inching nearer to becoming useful.
This guide is more about putting the pieces together in a meaningful way to enable you to start from scratch in your own applications, and less about building a production app.
Whenever you're ready, let's start with the Dashboard and React SPA section of the app, and start putting it all together.
Preparation for the Dashboard
First, we need to set up our routes and controllers to restrict access to the dashboard to authed users only.
config/routes.rb and replace the content with this:
Rails.application.routes.draw do # should come before public root authenticated :user do root 'app/dashboard#index' end root 'pages#home' devise_for :users end
We have the dashboard route only for authed users, a normal root route, and devise routes.
Let's ensure only authed users have access to our Dashboard.
And add devise's before action:
Adding Dashboard packs
Next we need to set up our JS packs and assets in the same way we did for
app/frontend/app/assets/styles/app-styles.scss. We can leave it empty for now.
app/frontend/packs/app.js and replace it's content with this:
import '@blueprintjs/icons/lib/css/blueprint-icons.css' import '@blueprintjs/core/lib/css/blueprint.css' import '../app/assets/styles/app-styles' import Rails from 'rails-ujs' Rails.start(); console.log('App Pack')
Similarly to application, it imports blueprint styles etc, but the only difference is that it's logging
App Pack to the console so we can be sure we've loaded the right pack.
Testing the dashboard
Now either register or login, and you should land on the Dashboard route, and see
App::Dashboard#index in the view instead of home.
You should also see
App Pack logged to the console.
In this Part, we added some basic user features, we cleaned up our files, organized our monolith to use Rails and React interchangabely, adding a powerful React library, and are prepared to start building our Dashboard SPA. There is a lot to go over for the Dashboard, so let's continue covering what we'll need to do in the next post.