Actually I’ve managed to do it server-side as follows, don’t know if there’s a simpler way:
# config/initializers/action_text.rb
module ActionText
Rails.application.reloader.to_prepare do
ContentHelper.allowed_attributes += ["target", "rel"]
unless ContentHelper.included_modules.include?(ContentHelperMonkeyPatch)
ContentHelper.include(ContentHelperMonkeyPatch)
end
unless Content.included_modules.include?(ContentMonkeyPatch)
Content.include(ContentMonkeyPatch)
end
end
end
# lib/action_text/content_helper_monkey_patch.rb
module ActionText
module ContentHelperMonkeyPatch
def custom_render_action_text(content)
local_base_url = request.base_url
self.prefix_partial_path_with_controller_namespace = false
rendered = render_action_text_attachments(content).render_links(local_base_url)
sanitize_action_text_content(rendered)
end
end
end
# lib/action_text/content_monkey_patch.rb
module ActionText
module ContentMonkeyPatch
def render_links(local_base_url)
content = fragment.replace("a") do |node|
unless node.attribute("href")&.value&.start_with?(local_base_url)
node.set_attribute("target", "_blank")
node.set_attribute("rel", "noreferrer noopener")
node.set_attribute("class", "external")
end
node
end
self.class.new(content, canonicalize: false)
end
end
end
# app/views/action_text/content/_layout.html.erb
<div class="trix-content">
<%= custom_render_action_text(content) %>
</div>