Flash messages are a crucial part of any web application, providing feedback to users after performing certain actions. Here we’ll walk you through building flash messages in a Rails 7 application using Tailwind CSS for styling, Stimulus for interactivity, and ViewComponent for modular UI elements.
Prerequisites
Before we begin, make sure you have the following installed:
- Ruby (>= 3.0)
- Rails (>= 7.0)
- ViewComponent (>= 3.5)
Step 1: Create a New Rails Project
Run the following command to generate a new application that uses Tailwind CSS for styling:
$ rails new flash_messages --css=tailwind
$ cd flash_messages
This also automatically installs our much needed Hotwire goodness in Stimulus (and Turbo). Check out this post if you’re looking for more ideas in setting up your application for front-end development.
Step 2: Create a Flash Message Component
ViewComponents allow you to create modular, reusable UI elements. Let’s generate a component for our flash messages:
$ rails generate component FlashMessage type message
create app/components/flash_message.rb
invoke tailwindcss
create app/components/flash_message.html.erb
This will create the FlashMessageComponent
class with a corresponding view template. Optionally, you can move these files inside a folder to allow your view components to be more organized (and namespaced):
# app/components/flash_message/component.rb
# app/components/flash_message/component.html.erb
Step 3: Implement the Flash Message Component
We will want to handle the different types of flash messages, and assign corresponding styles for each of them. With that, our component will now look something like this:
app/components/flash_message/component.rb
:
# app/components/flash_message/component.rb
module FlashMessage
class Component < ViewComponent::Base
attr_reader :type, :message
def initialize(type:, message:)
@type = type
@message = message
end
private
def color_classes
case type
when :success
'bg-green-100 border-green-400 text-green-700'
when :error
'bg-red-100 border-red-400 text-red-700'
when :warning
'bg-yellow-100 border-yellow-400 text-yellow-700'
when :notice
'bg-blue-100 border-blue-400 text-blue-700'
else
'bg-gray-100 border-gray-400 text-gray-700'
end
end
end
end
app/components/flash_message/component.html.erb
:
<!-- app/components/flash_message/component.html.erb -->
<div class='relative flex px-4 py-3 space-x-2 border <%= color_classes %>' role='alert'>
<strong class='font-bold'><%= message[:title] %></strong>
<span class='pl-5'>
<%= heroicon 'x-mark', options: { class: 'w-6 h-6 fill-current', role: 'button' } %>
</span>
</div>
You may use your favorite icon library as well (i.e. font-awesome), but I’ve found heroicons more fun to work with on Tailwind. There’s also a heroicon gem which will allow you to use a nice helper method to render your heroicon SVG’s. To make this available to your components, you may create a parent component class that includes your view helpers and have your components inherit from it:
# app/components/application_component.rb
class ApplicationComponent < ViewComponent::Base
include ApplicationHelper
include HeroiconHelper
end
# app/components/flash_message/component.rb
module FlashMessage
class Component < ApplicationComponent
# ...
end
end
Step 4: Create the Flash Messages Partial
Create a partial for rendering flash messages in app/views/shared/_flash_messages.html.erb
and add it in application.html.erb
:
<!-- app/views/shared/_flash_messages.html.erb -->
<% if flash.any? %>
<div class='inset-0 p-6 items-start justify-end'>
<div class='flex flex-col items-center justify-center'>
<% flash.each do |type, message| %>
<%= render FlashMessage::Component.new(type: type, message: message) %>
<% end %>
</div>
</div>
<% end %>
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<!-- ... -->
<body>
<%= render 'shared/flash_messages' %>
<!-- ... -->
</body>
</html>
Step 5: Set Up the Stimulus Controller
Stimulus will handle the interactivity of our flash messages. Generate a Stimulus controller:
$ rails generate stimulus FlashMessage
create app/javascript/controllers/flash_message_controller.js
Open app/javascript/controllers/flash_message_controller.js
and add the following code:
// app/javascript/controllers/flash_message_controller.js
import { Controller } from '@hotwired/stimulus'
// Connects to data-controller='flash-message'
export default class extends Controller {
connect() {
setTimeout(() => {
this.element.remove();
}, 5000) // Remove flash message after 5 seconds
}
close() {
this.element.remove()
}
}
Add the following attributes to your flash messsage elements to connect it to the stimulus controller:
<!-- app/views/shared/_flash_messages.html.erb -->
<% if flash.any? %>
<div data-controller='flash-message' class='inset-0 p-6 items-start justify-end'>
<!-- ... -->
</div>
<% end %>
<!-- app/components/flash_message/component.html.erb -->
<!-- ... -->
<%= heroicon 'x-mark', options: { 'data-action': 'click->flash-message#close', class: 'w-6 h-6 fill-current', role: 'button' } %>
<!-- ... -->
Step 6: Implement Flash Messages in Controllers
In your controllers, set up flash messages like this:
# app/controllers/some_controller.rb
def create
# ...
flash[:message] = 'Record was successfully created'
flash[:type] = :success
redirect_to some_path
end
def update
# ...
flash[:message] = 'Record was successfully updated'
flash[:type] = :success
redirect_to some_path
end
def destroy
# ...
flash[:message] = 'Record was successfully deleted'
flash[:type] = :error
redirect_to some_path
end
Step 7: Test It Out!
Start your Rails server and navigate through your application. Try performing actions that trigger flash messages to see them in action.
Conclusion
Congratulations! You have successfully implemented flash messages in your Rails 7 application using Tailwind CSS, Stimulus, and View Components. By combining these tools, you can easily create modular and interactive flash messages for your web application. This approach allows for clean separation of concerns and promotes code reusability, making it easier to maintain and extend your application in the future.
If you need any help with your Rails Application and development please reach out to us and we are happy to help.
Happy coding!
Ps. if you have any questions
Ask here