Back to home

Devise Part 3: Updating Our Devise Views With Tailwind CSS main image

Devise Part 3: Updating Our Devise Views With Tailwind CSS

In the previous post (part two), we changed our Devise setup to use Redis for sessions. This will be required going forward (but feel free to swap back to the cookie store).

Today, we will take a quick pivot to beautify our sign in page using TailwindCSS and TailwindUI.

We are going to specifically implement the demo sign in component that comes for free.

Source code can be found here.


  1. Basic familiarity with setting up a new Rails project.
  2. Some familiarity with TailwindCSS would be useful as we won't really cover how it works.

Getting started

We will be working from the source code found here.

# Clone and change into the project $ git clone $ cd demo-rails-7-with-devise-series # Continue from part 2 - warning that Redis required $ git checkout 2-using-redis-sessions # Add required gems and setup the files $ bundler add tailwindcss-rails $ bin/rails tailwindcss:install # We want to update our Devise views, so we will need to scaffold them $ bin/rails generate devise:views

Note that since we want to update our Devise views, we will need to scaffold them. This is done in the last command of the above.

The bin/rails tailwindcss:install went ahead and added a bin/dev file and updated our to run a command to watch TailwindCSS.

To see the fruits of our labor, start the server with bin/dev (instead of bin/rails s).

Updating our Devise views

I went ahead and did a lot of the work for our Devise view here in converting over the desired component to ERB.

Update app/views/devise/sessions/new.html.erb to the following:

<div class="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8" > <div class="max-w-md w-full space-y-8"> <div> <img class="mx-auto h-12 w-auto" src="" alt="Workflow" /> <h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900"> Sign in to your account </h2> <%- if devise_mapping.registerable? && controller_name != 'registrations' %> <p class="mt-2 text-center text-sm text-gray-600"> Or <%= link_to "sign up", new_registration_path(resource_name), class: "font-medium text-indigo-600 hover:text-indigo-500" %> </p> <% end %> </div> <%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { data: { turbo: false} }) do |f| %> <div class="mt-8 space-y-6"> <input type="hidden" name="remember" value="true" /> <div class="rounded-md shadow-sm -space-y-px"> <div> <%= f.label :email, class: "sr-only", for: "email-address" %> <%= f.email_field :email, id: "email-address", autofocus: true, autocomplete: "email", placeholder: "Email address", class: "appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" %> </div> <div> <%= f.label :password, for: "password", class: "sr-only" %> <%= f.password_field :password, id: "password", autocomplete: "current-password", placeholder: "Password", class: "appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" %> </div> </div> <% if devise_mapping.rememberable? %> <div class="flex items-center justify-between"> <div class="field flex items-center"> <%= f.check_box :remember_me, class: "h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" %> <%= f.label :remember_me, class: "ml-2 block text-sm text-gray-900" %> </div> <div class="text-sm"> <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> <%= link_to "Forgot your password?", new_password_path(resource_name), class: "font-medium text-indigo-600 hover:text-indigo-500" %> <% end %> </div> </div> <% end %> <div class="actions"> <%= f.submit "Log in", class: "actions group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %> </div> </div> <% end %> </div> </div>

You will also need to update the app/views/layouts/application.html.erb view to remove all the classes from main:

<!DOCTYPE html> <html> <head> <title>DemoRails7WithDeviseSeries</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> </head> <body> <main><%= yield %></main> </body> </html>

If you now refresh the page, we will have a lovely component in place of what we had before!



...and after:



Go through the normal flow of sign-in to confirm that it all works as expected from the previous parts.


In this part, we detoured to add in Tailwind CSS and make our sign in page look a little livelier.

Although we do not cover it, you could take this further by beautifying the other sign up page that we have (you'll notice it still looks crummy) but I won't be doing that here as we can confirm that Tailwind is up and working.

Resources and further reading

Photo credit: oscrse

Personal image

Dennis O'Keeffe

  • Melbourne, Australia

Hi, I am a professional Software Engineer. Formerly of Culture Amp, UsabilityHub, Present Company and NightGuru.
I am currently working on, Den Dribbles and LandPad .


Get fresh posts + news direct to your inbox.

No spam. We only send you relevant content.