{"id":19016217,"date":"2026-09-10T06:13:46","date_gmt":"2026-09-10T06:13:46","guid":{"rendered":"https:\/\/wordpress.org\/support\/topic\/elementor-popups-widget-rendered-twice\/"},"modified":"2026-09-10T06:13:46","modified_gmt":"2026-09-10T06:13:46","slug":"elementor-popups-widget-rendered-twice","status":"publish","type":"topic","link":"https:\/\/wordpress.org\/support\/topic\/elementor-popups-widget-rendered-twice\/","title":{"rendered":"Elementor popups: widget rendered twice"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hi Elliot<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I have run into a reproducible problem with the Elementor Forms integration when the form lives inside an Elementor popup. The widget is rendered a second time into the same container, and depending on timing it can end up in a state where it paints the box but never produces a token, which leaves a legitimate visitor unable to submit the form.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What I think is happening: the form inside the popup has already been processed by cfturnstile_init_elementor_forms(), which renders a widget into the container and marks the form cft-processed. When the popup opens, the elementor\/popup\/show handler in js\/integrations\/elementor-forms.js then runs turnstile.remove(widget) followed by turnstile.render(widget, \u2026) on that same container. turnstile.remove() does not empty the container, so the render() call appends a second child div next to the previous one. The container ends up with two child divs and the form ends up with two cf-turnstile-response inputs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">How to reproduce:<\/p>\n\n\n\n<ol>\n<li>Elementor Pro popup containing a form, with the Elementor integration enabled in the plugin settings.<\/li>\n\n\n\n<li>Open the popup and inspect the widget container in the console: const f = document.querySelector(&#8216;form.elementor-form&#8217;);<br \/>const w = f.querySelector(&#8216;.cf-turnstile&#8217;);<br \/>w.children.length;<br \/>[\u2026f.querySelectorAll(&#8216;[name=&#8221;cf-turnstile-response&#8221;]&#8217;)].map(i =&gt; i.value.length);<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">What I see: two child divs, and two response inputs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On one of my popups the second input filled in normally after a few seconds. On another popup, on the same site and with the same settings, both inputs stayed empty even after eight seconds, and the form could not be submitted at all. So it is intermittent, and when it goes wrong it silently blocks a real visitor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Emptying the container by hand and rendering again always recovers it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>turnstile.remove(w);\nw.innerHTML = '';\nturnstile.render(w, { sitekey: cfturnstileElementorSettings.sitekey });<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and the token arrives a few seconds later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suggested fix, clearing the container before re-rendering in the elementor\/popup\/show handler:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>try { turnstile.remove(widget); } catch (e) {}\nwidget.innerHTML = '';\nturnstile.render(widget, { ... });<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A tidier option might be to skip the re-render altogether when the existing widget still responds to turnstile.getResponse(), so that a challenge the visitor is in the middle of solving is never thrown away.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One thing worth flagging if you consider a different approach: a timeout based watchdog would not be safe here. In Managed mode the absence of a token can simply mean the visitor is still working through an interactive challenge, and re-rendering underneath them would discard it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Versions: WordPress with Elementor 4.1.1, Elementor Pro 4.1.0, Simple CAPTCHA with Cloudflare Turnstile 1.42.3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Happy to test a patch on my side if that helps. I use the plugin on a live site with a fair amount of Elementor forms, so I can try things out quickly. If it is ever easier to go through this outside the forum, just tell me where to write.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thanks!<\/p>\n","protected":false},"template":"","class_list":["post-19016217","topic","type-topic","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19016217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic"}],"about":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19016217\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/media?parent=19016217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}