Skip to content
Go back

Adding a Close Button to Flash Messages in Rails

Updated:
Adding a Close Button to Flash Messages in Rails

Note (2025): This post was originally written in 2011 for Rails 2/3 and shows link_to_function, which was removed in Rails 4. Modern Rails apps typically use Stimulus/Turbo or UI frameworks like Bootstrap/Tailwind for dismissible flash messages. A Rails 7+ example is included at the end.

Rails’ flash provides a way to pass temporary messages between actions. Anything you place in the flash is available for the next request and then cleared automatically. This makes it ideal for displaying notices and alerts — for example, after creating a record:

class PostsController < ActionController::Base
  def create
    # save post
    flash[:notice] = "Post successfully created"
    redirect_to @post
  end

  def show
    # no need to explicitly assign the flash; Rails exposes it automatically
  end
end

In the view:

<% if flash[:notice] %>
  <div class="notice"><%= flash[:notice] %></div>
<% end %>

Example of a Rails flash notice rendered in the view


The Problem

By default, flash messages stay visible until the next page load or redirect. Users often expect to dismiss them without refreshing the page.


The Original 2011 Solution (historical)

Add an explicit close control that hides the flash element:

<% flash.each do |name, msg| %>
  <%= content_tag :div, id: "flash_#{name}" do %>
    <%= msg %>
    <%= link_to_function image_tag('icons/cross.png'),
      onclick: "document.getElementById('flash_#{name}').style.display='none'" %>
  <% end %>
<% end %>

Styling

#flash_notice,
#flash_error,
#flash_alert {
  padding: 5px 8px;
  margin: 10px 0;
}

#flash_notice {
  background-color: #faf0e6;
  border: 1px solid #5d871b;
  color: #5d871b;
}

#flash_error,
#flash_alert {
  background-color: #faf0e6;
  border: 1px solid #a94442;
  color: #a94442;
}

Example of a Rails flash notice rendered in the view

Be sure to include an icon (e.g., cross.png) in your images/icons folder.


Modern Rails 7+ Approach with Stimulus

Prefer a small Stimulus controller for clean, accessible, and framework-agnostic behavior.

app/javascript/controllers/flash_controller.js

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  close() {
    this.element.remove();
  }
}

app/views/shared/_flash.html.erb

<% flash.each do |type, message| %>
  <div data-controller="flash" class="flash <%= type %>">
    <%= message %>
    <button type="button"
            data-action="click->flash#close"
            aria-label="Close">

    </button>
  </div>
<% end %>

Example CSS (Tailwind-friendly; adjust to your stack)

.flash {
  @apply relative mb-2 rounded px-4 py-2;
}
.flash.notice {
  @apply border border-green-400 bg-green-100 text-green-800;
}
.flash.alert,
.flash.error {
  @apply border border-red-400 bg-red-100 text-red-800;
}
.flash button {
  @apply absolute top-1 right-2 cursor-pointer text-lg font-bold;
}

Why this is better today


Wrap-up

Keep the original snippet as a historical reference, but favor the Stimulus approach for modern Rails apps. It’s cleaner, accessible, and future-proof.


You might also like


Share this post on:

Previous Post
How to Use Forked NPM Dependencies
Next Post
The Future of Web Performance: Beyond Core Web Vitals