As the pages are not full rendered, and only the partial, flash messages are not displayed.
First we want to trigger Immediatly the creation of the flash message and not during the page redirection or turbo_stream (Remember turbo_stream only refresh the targeted DOM part and not the whole page)
In the controller actions replace flash[:notice] = “ message….” by flash.now[:notice] = “ton message …”
As we will target the flash messages with Turbo Stream we need to add a turbo frame with id=”flashes” dans notre layouts/application.html.erb
# app/views/layouts/application.html.erb
[...]
<%= turbo_frame_tag "flashes" do%>
<%= render "shared/flashes" %>
<% end %>
[...]
We can now update the turbo_stream view tu “push the flash partial to the view”
# app/views/action.turbo_stream.erb
[...]
<%= turbo_stream.prepend "flashes", partial: "shared/flashes" %>
As we want the flash content to be remove from the dom after a css animation, we have to add the css animation and Use Stimulus
Create css animation
//app/assets/stylesheets/config/_animations.scss
@keyframes display-and-fade-away {
0%, 100% {
opacity:0
}
5%, 60% {
opacity:1
}
}
DON’T forget to add this new file to your asset pipeline
// app/assets/stylesheets/application.scss
[...]
@import "config/animations";
[...]
Add the animation to the .alert
.alert {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 1000;
animation: display-and-fade-away 5s both;
}
Create a stimulus controller for the flash partial removal:
-> rails g stimulus removal
create app/javascript/controllers/removal_controller.js
# app/javascript/controllers/removals_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
remove() {
this.element.remove()
}
}
Update the partial with the Stimulus controller & stimulus action. The action is triggered at the end the flash animation using animationend event
# app/views/layouts/_flashes.html.erb
<% if notice %>
<div class="alert alert-info alert-dismissible fade show m-1" role="alert"
data-controller="removals"
data-action="animationend->removals#remove" >
<%= notice %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
</button>
</div>
<% end %>
<% if alert %>
<div class="alert alert-warning alert-dismissible fade show m-1" role="alert"
data-controller="removals"
data-action="animationend->removals#remove" >
<%= alert %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
</button>
</div>
<% end %>