Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Cloudflare verification widget is not rendered when visiting the turbo links enabled page #63

Open
yash-learner opened this issue Jun 23, 2023 · 4 comments · May be fixed by #186
Open

Comments

@yash-learner
Copy link

I'm currently using your rails_cloudflare_turnstile gem in a Rails project and have encountered an issue. The gem seems to not work properly with pages using Turbolinks.

The Cloudflare widget is not rendered on a page which has turbolinks enabled, but the Cloudflare widget gets rendered on the same page on a full-page reload (refresh).

The things I tried

  • I have disabled the turbolinks for those particular links by adding data-turbolinks="false" and data: { turbolinks: false }. This is working, as disabling the turbolinks on the link will make a full-page reload.
  • I tried modifying the script in the
    content_tag(:script, src: js_src, async: async, defer: defer) do
    by adding the attribute 'data-turbolinks-track': 'reload'. This attribute tells to do a full page reload when visiting the turbo links, but this change does not work and the widget is not rendered when visits pages with turbolinks enabled.
  content_tag(
    :script,
    src: js_src,
    async: async,
    "data-turbolinks-track": 'reload',
  ) { '' }
  • I have hooked the script into turbolinks:load event having data-turbolinks-track="reload" - This works and renders the widget when visiting the turbolinks enabled pages. I have done this in two ways.

application.js

document.addEventListener("turbolinks:load", function () {
  let scriptSrc = "https://challenges.cloudflare.com/turnstile/v0/api.js";

  let existingScript = document.querySelector(`script[src="${scriptSrc}"]`);

  existingScript.setAttribute("data-turbolinks-track", "reload");
});

This can a problem because in the future if the version of Cloudflare is changed to v0 to v1 ..


I had overided the method in cloudflare_turnstile.rb initializer

module RailsCloudflareTurnstile
  module ViewHelpers
    def cloudflare_turnstile_script_tag(async: true, defer: false)
      javascript = <<~JAVASCRIPT
        document.addEventListener("turbolinks:load", function() {
          let script = document.createElement("script");
          script.src = "#{RailsCloudflareTurnstile.enabled? ? js_src : mock_js}";
          script.async = #{async};
          script.defer = #{defer};
          script.dataset.turbolinksTrack = "reload";
          document.head.appendChild(script);
        });
      JAVASCRIPT

      content_tag(:script, javascript.html_safe)
    end
  end
end

I would like to ask if there's a workaround or a possible patch to make it compatible with Turbolinks. I believe this would greatly enhance the gem's versatility and usability for many Rails developers.

Looking forward to hearing from you soon. Thank you for your time and consideration.

@AliOsm
Copy link
Contributor

AliOsm commented Jun 24, 2023

This could be solved with the following:

  1. Create a Stimulus controller with the following content:
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    if (document.querySelector(".cf-turnstile") && window.turnstile) {
      window.turnstile.render(".cf-turnstile");
    }
  }
}
  1. Wrap cloudflare_turnstile in a div with data-controller="cloudflare-turnstile":
<div data-controller="cloudflare-turnstile">
  <%= cloudflare_turnstile %>
</div>

It works fine, what do you think?

@yash-learner
Copy link
Author

yash-learner commented Jul 19, 2023

Thanks @AliOsm, for the suggestion and please accept my apologies for the delayed response.

It works fine, and I feel it is a cleaner and better solution.

Thank you for sharing it.👍

@PapePathe
Copy link

It works fine, i feel like this should be in the readme.

@jamesst20
Copy link

jamesst20 commented Jun 19, 2024

@Roguelazer

The proper fix is to tell turbo to simply reload the script

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer data-turbo-track="reload" data-turbo-temporary="true"></script>

Could you please let us add custom configuration for that and include documentation? Hotwire + Turbo is used a lot by Rails community it even ships by default with Rails 7 now.

Temporary patch that works. Add this in the initializer:

module RailsCloudflareTurnstileTurboPatch
  def cloudflare_turnstile_script_tag(async: true, defer: true)
    super.sub("></script>", " data-turbo-track=\"reload\" data-turbo-temporary=\"true\"></script>").html_safe
  end
end


RailsCloudflareTurnstile::ViewHelpers.prepend(RailsCloudflareTurnstileTurboPatch)

@yash-learner it seems you said you tried but it does work fine. Turbolinks has been long dead, you should consider upgrading to Turbo. I use Turbo v8

Edit

The trick was data-turbo-temporary="true"

@guillemap guillemap linked a pull request Nov 9, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants