diff --git a/app/controllers/turbo_controller.rb b/app/controllers/turbo_controller.rb
new file mode 100644
index 0000000..600e9d2
--- /dev/null
+++ b/app/controllers/turbo_controller.rb
@@ -0,0 +1,18 @@
+class TurboController < ApplicationController
+ class Responder < ActionController::Responder
+ def to_turbo_stream
+ controller.render(options.merge(formats: :html))
+ rescue ActionView::MissingTemplate => error
+ if get?
+ raise error
+ elsif has_errors? && default_action
+ render rendering_options.merge(formats: :html, status: :unprocessable_entity)
+ else
+ redirect_to navigation_location
+ end
+ end
+ end
+
+ self.responder = Responder
+ respond_to :html, :turbo_stream
+end
diff --git a/app/controllers/users/devise_controller.rb b/app/controllers/users/devise_controller.rb
new file mode 100644
index 0000000..c3aafd5
--- /dev/null
+++ b/app/controllers/users/devise_controller.rb
@@ -0,0 +1,18 @@
+class Users::DeviseController < ApplicationController
+ class Responder < ActionController::Responder
+ def to_turbo_stream
+ controller.render(options.merge(formats: :html))
+ rescue ActionView::MissingTemplate => error
+ if get?
+ raise error
+ elsif has_errors? && default_action
+ render rendering_options.merge(formats: :html, status: :unprocessable_entity)
+ else
+ redirect_to navigation_location
+ end
+ end
+ end
+
+ self.responder = Responder
+ respond_to :html, :turbo_stream
+end
diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb
index 6b68ee6..9e4c6b5 100644
--- a/app/views/devise/shared/_error_messages.html.erb
+++ b/app/views/devise/shared/_error_messages.html.erb
@@ -2,7 +2,7 @@
<% resource.errors.full_messages.each do |message| %>
- - <%= message %>
+ - <%= message %>
<% end %>
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index b75750f..91efcee 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -3,6 +3,21 @@ require 'digest'
require 'securerandom'
# frozen_string_literal: true
+# Create custom failure for turbo
+class TurboFailureApp < Devise::FailureApp
+ def respond
+ if request_format == :turbo_stream
+ redirect
+ else
+ super
+ end
+ end
+
+ def skip_format?
+ %w(html turbo_stream */*).include? request_format.to_s
+ end
+end
+
# Assuming you have not yet modified this file, each configuration option below
# is set to its default value. Note that some are commented out while others
# are not: uncommented lines are intended to protect your configuration from
@@ -44,6 +59,7 @@ Devise.setup do |config|
# ==> Controller configuration
# Configure the parent class to the devise controllers.
# config.parent_controller = 'DeviseController'
+ config.parent_controller = 'TurboController'
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
@@ -289,6 +305,7 @@ Devise.setup do |config|
#
# The "*/*" below is required to match Internet Explorer requests.
# config.navigational_formats = ['*/*', :html]
+ config.navigational_formats = ['*/*', :html, :turbo_stream]
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get
@@ -302,10 +319,11 @@ Devise.setup do |config|
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
#
- # config.warden do |manager|
- # manager.intercept_401 = false
- # manager.default_strategies(scope: :user).unshift :some_external_strategy
- # end
+ config.warden do |manager|
+ manager.failure_app = TurboFailureApp
+ # manager.intercept_401 = false
+ # manager.default_strategies(scope: :user).unshift :some_external_strategy
+ end
# ==> Mountable engine configurations
# When using Devise inside an engine, let's call it `MyEngine`, and this engine