Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/Resources/views/storefront/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,86 @@
{{ parent() }}

{% if config('CleverPushShopwarePlugin.config.channelId') is not empty %}
{#
CP-11185: The CleverPush SDK installs a delegated global click handler
that calls preventDefault() and stopImmediatePropagation() on every
click it considers "handleable". For Shopware-internal anchor links
(e.g. the product review tab via href="#review-tab-..." with
data-remote-click="true") this incorrectly cancels the native
tab-switch / hash navigation.

Until the SDK exposes finer-grained shouldHandle() rules, we install
our own bubble-phase delegated listener on `document` BEFORE the
async CleverPush loader runs. Because click listeners on the same
target fire in registration order, ours fires first and uses
stopImmediatePropagation() to prevent the SDK's later-registered
handler (and any window-level fallback) from seeing the event.

We do this only for elements that Shopware (or themes built on it)
uses for in-page navigation, so legitimate CleverPush tracking on
outbound / non-anchor clicks keeps working.
#}
<script>
(function () {
if (typeof document === 'undefined' || !document.addEventListener) {
return;
}

/*
* Selectors for elements that Shopware (or themes built on it)
* use for in-page navigation / interactive widgets and that the
* CleverPush SDK must NOT intercept. Notably the product-detail
* review tab link uses href="#review-tab-..." together with
* data-remote-click="true".
*/
var INTERNAL_NAV_SELECTOR = [
'a[href^="#"]',
'[data-remote-click]',
'[data-bs-toggle]',
'[data-toggle]',
'.product-detail-reviews-link'
].join(', ');

function isInternalNavigation(target) {
if (!target || typeof target.closest !== 'function') {
return false;
}
try {
return !!target.closest(INTERNAL_NAV_SELECTOR);
} catch (e) {
return false;
}
}

/*
* Register a delegated click listener on `document` BEFORE the
* async CleverPush loader is requested. Listeners on the same
* EventTarget fire in registration order, so this one runs
* before the SDK's later-registered delegated handler. By
* calling stopImmediatePropagation() for Shopware-internal
* anchors, we keep the SDK from invoking its preventDefault()
* / stopImmediatePropagation() on them, which previously
* blocked Shopware's hash-based tab switch (e.g. the review
* tab on the product detail page – CP-11185).
*
* Shopware's own RemoteClickPlugin and Bootstrap toggles
* attach element-level listeners that fire in the target
* phase before this document-level bubble handler, so their
* behavior is preserved.
*/
document.addEventListener('click', function (event) {
var target = event && event.target;
if (!target || !isInternalNavigation(target)) {
return;
}
if (typeof event.stopImmediatePropagation === 'function') {
event.stopImmediatePropagation();
} else if (typeof event.stopPropagation === 'function') {
event.stopPropagation();
}
}, false);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guard over-blocks all document-level handlers, not just CleverPush

Medium Severity

Calling stopImmediatePropagation() on document in the bubble phase blocks ALL subsequently-registered document-level and window-level click handlers—not just CleverPush's. Because the inline script runs before any async/deferred JavaScript, this affects every other tool that uses document-level delegation for click tracking (e.g., Google Analytics, Matomo, Hotjar, or other Shopware plugins). The a[href^="#"] selector is especially broad, matching every hash link on the page including common href="#" JavaScript-action anchors, making silent breakage of analytics or other plugins likely.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d3c0819. Configure here.

})();
</script>
<script src="https://static.cleverpush.com/channel/loader/{{ config('CleverPushShopwarePlugin.config.channelId') }}.js" async></script>
{% endif %}
{% endblock %}