Skip to content

Commit 8a54a32

Browse files
authored
Merge pull request #35 from tanthammar/patch-2
Fix multiple instances
2 parents cafdf3c + 7822770 commit 8a54a32

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

resources/views/components/turnstile.blade.php

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,60 @@
99

1010
<x-dynamic-component :component="$fieldWrapperView" :field="$turnstile">
1111

12-
<div x-data="{
13-
state: $wire.entangle('{{ $statePath }}').defer
12+
<div wire:ignore
13+
x-load-js="['https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=onTurnstileLoad']"
14+
x-data="{
15+
state: $wire.entangle('{{ $statePath }}').defer,
16+
widgetId: null,
1417
}"
15-
wire:ignore
16-
x-load-js="['https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback']"
1718
x-init="(() => {
18-
let options= {
19+
let options = {
20+
sitekey: '{{config('turnstile.turnstile_site_key')}}',
21+
theme: '{{ $theme }}',
22+
size: '{{ $size }}',
23+
language: '{{ $language }}',
1924
callback: function (token) {
2025
$wire.set('{{ $statePath }}', token)
2126
},
22-
23-
errorCallback: function () {
27+
'error-callback': function () {
2428
$wire.set('{{ $statePath }}', null)
25-
},
29+
}
2630
}
2731
28-
window.onloadTurnstileCallback = () => {
29-
turnstile.render($refs.turnstile, options)
32+
// Render widget when Turnstile API is ready
33+
const renderWidget = () => {
34+
if (!window.turnstile || !$refs.turnstile || widgetId !== null) {
35+
return;
36+
}
37+
38+
widgetId = turnstile.render($refs.turnstile, options);
3039
}
3140
32-
resetCaptcha = () => {
33-
turnstile.reset($refs.turnstile)
41+
// Called when Turnstile API loads
42+
window.onTurnstileLoad = () => {
43+
renderWidget();
3444
}
3545
36-
$wire.on('reset-captcha', () => resetCaptcha())
46+
// If API already loaded (on re-render), render immediately
47+
if (window.turnstile) {
48+
renderWidget();
49+
}
3750
38-
const observer = new IntersectionObserver((entries) => {
39-
entries.forEach(entry => {
40-
if (entry.isIntersecting &&
41-
window.turnstile &&
42-
!$refs.turnstile.querySelector('.cf-turnstile')) {
43-
turnstile.render($refs.turnstile, options);
44-
}
45-
});
46-
}, { threshold: 0.1 })
51+
$wire.on('reset-captcha', () => {
52+
if (widgetId !== null && window.turnstile) {
53+
turnstile.reset(widgetId);
54+
}
55+
})
4756
48-
if ($refs.turnstile) {
49-
observer.observe($refs.turnstile);
57+
// Cleanup when component is destroyed
58+
return () => {
59+
if (widgetId !== null && window.turnstile) {
60+
turnstile.remove(widgetId);
61+
widgetId = null;
62+
}
5063
}
5164
})()"
5265
>
53-
<div data-sitekey="{{config('turnstile.turnstile_site_key')}}"
54-
data-theme="{{ $theme }}"
55-
data-language="{{ $language }}"
56-
data-size="{{ $size }}"
57-
x-ref="turnstile"
58-
>
59-
</div>
66+
<div x-ref="turnstile"></div>
6067
</div>
6168
</x-dynamic-component>

0 commit comments

Comments
 (0)