{"id":14969847,"url":"https://github.com/joshmn/turbo_flash","last_synced_at":"2025-10-26T10:31:15.327Z","repository":{"id":59158216,"uuid":"388903413","full_name":"joshmn/turbo_flash","owner":"joshmn","description":"Automagically include your flash messages in your Ruby on Rails Hotwire TurboStream responses.","archived":false,"fork":false,"pushed_at":"2023-08-18T19:30:36.000Z","size":29,"stargazers_count":61,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-31T18:14:48.526Z","etag":null,"topics":["hotwire","hotwire-turbo","rails","ruby-on-rails","turbo"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshmn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-07-23T19:15:31.000Z","updated_at":"2024-05-12T05:15:01.000Z","dependencies_parsed_at":"2022-09-13T20:10:19.554Z","dependency_job_id":"8110fde0-92ed-42de-b7cf-195a4f0fb580","html_url":"https://github.com/joshmn/turbo_flash","commit_stats":{"total_commits":7,"total_committers":1,"mean_commits":7.0,"dds":0.0,"last_synced_commit":"ff7af0847e5e192de69d69aab149ed6cbc06d85e"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshmn%2Fturbo_flash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshmn%2Fturbo_flash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshmn%2Fturbo_flash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshmn%2Fturbo_flash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshmn","download_url":"https://codeload.github.com/joshmn/turbo_flash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238310305,"owners_count":19450839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hotwire","hotwire-turbo","rails","ruby-on-rails","turbo"],"created_at":"2024-09-24T13:42:29.681Z","updated_at":"2025-10-26T10:31:10.055Z","avatar_url":"https://github.com/joshmn.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Notice\n\nFor the sake of your application, consider using [HotFlash](https://github.com/joshmn/hotflash) instead.\n\n# TurboFlash\n\nAutomagically include your flash messages in your Ruby on Rails [TurboStream](https://github.com/hotwired/turbo-rails) responses.\n\n![Video demo](https://i.imgur.com/pVqX9ZV.gif)\n\n## Usage\n\nBy default, TurboFlash will inherit all flashes that you normally set. This can be turned off with the `inherit_flashes`\nconfiguration flag.\n\nTo explicitly set flashes, TurboFlash exposes a `flash.turbo` method that's similar to `flash`:\n\n```ruby\nclass UsersController \u003c ApplicationController\n  def update\n    @user = current_user\n    unless @user.valid_password?(user_params[:current_password])\n      @user.errors.add(:current_password, \"is invalid.\")\n      return respond_to do |f|\n        f.html do \n          flash.now[:notice] = \"There was an error.\"\n          render :show\n        end\n        f.turbo_stream do\n          flash.turbo[:notice] = \"There was an error.\"\n          render turbo_stream: turbo_stream.replace(@user, partial: 'form')\n        end \n      end\n    end\n    \n    # ... \n  end\n  \n  private \n  \n  def user_params\n    params.require(:user).permit(:current_password, :password, :password_confirmation)\n  end\nend\n```\n\nOf course, the response will be what you expect:\n\n```ruby\nturbo_stream.replace(@user, partial: 'form')\n```\n\nTurboFlash will also automatically inject the following into your Turbo response:\n\n```ruby\nturbo_stream.update(\"flash\", partial: \"shared/flash\", locals: { role: :notice, message: \"There was an error.\" })\n```\n\nIf you want to get more granular, use `flash.turbo#set_options`:\n\n```ruby \nflash.turbo.set_options(action: :append)[:notice] = \"This will be appended.\"\n```\n\nYou could even:\n\n```ruby \nflash.turbo.set_options(action: :append, partial: \"layouts/_cool_awesome_flash\")[:error] = \"This will be appended from the partial cool_awesome_flash with an error role.\"\n```\n\nThe defaults are customizable and shown below.\n\n## Installation\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'turbo_flash'\n```\n\nAnd then execute:\n```bash\n$ bundle\n```\n\nCreate a partial of `shared/_flash.html.erb`:\n\n```erb \n\u003cdiv class=\"flash flash-\u003c%= local_assigns[:role] %\u003e\"\u003e\n  \u003c%= local_assigns[:message] %\u003e\n\u003c/div\u003e\n```\n\nEnsure that the TurboStream target — a tag with an `id` of `flash` exists in your layout:\n\n```erb\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003c%= csrf_meta_tags %\u003e\n    \u003c%= csp_meta_tag %\u003e\n\n    \u003c%= stylesheet_link_tag 'application', media: 'all', data: { turbo_track: :reload } %\u003e\n    \u003c%= javascript_pack_tag 'application', data: { turbo_track: :reload } %\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003cdiv id=\"flash\"\u003e\n      \u003c% flash.each do |role, message| %\u003e\n        \u003c%= render(partial: 'shared/flash', locals: { role: role, message: message }) %\u003e\n      \u003c% end %\u003e\n    \u003c/div\u003e\n    \n    \u003c%= yield %\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Turbo frames (instead of *.turbo_stream.erb)\n\nWhen using Turbo Frames, while the controller response will be injected with the relevant turbo_stream tags, Turbo will\nonly render the matching Turbo Frame content, and ignore the turbo_streams. To get around this, you can utilize the\nturbo layout `turbo_rails/frame.html.erb` and use `turbo_stream_from` to send the updates back to the browser. For example:\n\n```erb\n# app/views/layouts/turbo_rails/frame.html.erb\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003c%= yield :head %\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \n    \u003c% flash.turbo.flashes.each do |role, message| %\u003e\n      \u003c%= Turbo::StreamsChannel.broadcast_prepend_to current_user, :alerts, target: \"alerts\",\n      partial: 'shared/flash', locals: { role:, message: } %\u003e \u003c%# customize this based on your project %\u003e\n    \u003c% end %\u003e\n    \n    \u003c%= yield %\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Configuration\n\nIn an initializer (defaults are shown):\n\n```\nTurboFlash.configure do |config|\n  # make all flashes TurboFlash-flashes\n  # config.inherit_flashes = true \n  \n  # clear the TurboFlash target if there are no flashes in a TurboStream response\n  # config.clear_target_unless_flashed = true \n  \n  # the default TurboStream target element ID\n  # config.target = \"flash\"\n  \n  # the default TurboStream action\n  # config.action = :update \n  \n  # the default TurboStream partial\n  # config.partial = 'shared/flash'\n  \n  # the default flash key variable name\n  # config.key = :role \n  \n  # the default flash message variable name\n  # config.value = :message \nend\n```\n\n## Gotchas\n\nIf `TurboFlash.configuration.inherit_flashes` is `false`, and you want to copy over the regular flashes,\nyou can invoke `flash.turbo!(options = {})` to copy over the flashes that are currently stored in the session.\n\nIf `TurboFlash.configuration.clear_target_unless_flashed` is `false`, and you would like to clear flashes in the TurboStream\nresponse, you can invoke `flash.turbo.clear_target!` to clear the TurboStream target if there are no flashes.\n\nIf you want to clear all potential TurboFlashes, call `flash.turbo.clear!`\n\n## Contributing\n\nThere wasn't much thought put into this, but it works for me, so it might work for you!\n\n## License\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshmn%2Fturbo_flash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshmn%2Fturbo_flash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshmn%2Fturbo_flash/lists"}