Skip to content

Send view_item again when the shopper picks another combination - #186

Draft
boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:feat/view-item-on-combination-change-20268
Draft

boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:feat/view-item-on-combination-change-20268

Conversation

@boo-code

Copy link
Copy Markdown
Questions Answers
Description? The product page swaps a handful of blocks over AJAX and pushes a new URL instead of reloading when a shopper picks another combination. displayFooterProduct, which carries view_item, is not one of those blocks, so Google Analytics keeps reporting the combination the page was opened with for the whole visit. view_item is now also sent from displayProductAdditionalInfo, which is one of the blocks that refresh returns - only for that refresh, so a normal render still reports exactly once. ga_tag.tpl wraps its code in DOMContentLoaded, which cannot fire again in an already-loaded page, so the refreshed block uses a template without that wrapper.
Type? bug fix
BC breaks? no
Deprecations? no
Fixed ticket? Fixes PrestaShop/PrestaShop#20268.
Sponsor company
How to test? Set a GA4 measurement ID, open a product with combinations and watch the network tab or GA4 DebugView. On load one view_item is sent for the default combination. Pick another size or colour: before, nothing is sent and GA still shows the first combination; after, a second view_item arrives with item_id <product>-<combination> and the matching item_variant. Opening a quickview still sends nothing, and switching combinations inside a quickview still sends nothing.

Measured

PrestaShop 9.2.0, product 1 of the demo catalogue (8 combinations). The shopper switches to combination 3, M / White, which is what the theme posts as group[1]=2&group[2]=8 to the product refresh:

before
  product page                     view_item events: 1   item_id "1-1"
  refresh -> combination 3         view_item events: 0   (product_additional_info, 4081 bytes)

after
  product page                     view_item events: 1   item_id "1-1"        <- unchanged
  refresh -> combination 3         view_item events: 1   item_id "1-3"        (4625 bytes)
                                   item_variant "M - White", price 80, currency EUR
                                   DOMContentLoaded wrappers: 0
  refresh with quickview=1         view_item events: 0                        <- unchanged

The page-load count staying at 1 is the point: the new hook returns nothing unless the request is the product refresh, so nothing is double-counted.

Notes for review

  • Why not send page_view too. GA4's enhanced measurement already reports page changes from browser history events, and the theme's combination switch goes through history.pushState (themes/_core/js/product.js). Sending our own page_view would double-count it. The e-commerce event is the part GA4 cannot infer, which is why only view_item is sent.
  • Why displayProductAdditionalInfo. ProductController returns a fixed set of rendered partials for action=refresh, and catalog/_partials/product-additional-info.tpl - which both default themes render as {hook h='displayProductAdditionalInfo' product=$product} - is one of them. The theme replaces that block with the response, so a <script> inside it runs, with $product already presented for the newly selected combination. No new endpoint and no extra request.
  • Why a second template. ga_tag.tpl is document.addEventListener('DOMContentLoaded', ...). That event has long fired by the time the block is injected, so the code would never run. ga_tag_immediate.tpl is the same file without the wrapper. Adding a flag to ga_tag.tpl instead would silently drop the wrapper for every event on any theme that overrides that template, so it is left untouched.
  • Guards: only action=refresh with ajax, never quickview, and only on the product controller. Classic's quickview.tpl inlines the same hook, hence the explicit quickview check.
  • The is_array() || ArrayAccess check on the product template variable is the same guard as Prevent fatal error when product template variable is a Product object #181 on the sibling hook; if that PR lands first the two sites should share it.
  • Version bump. 6.0.0 is released, so an upgrade-6.0.0.php would not run on shops already on it - the hook would never be registered and the fix would be inert. Hence 6.1.0 plus upgrade/upgrade-6.1.0.php. If you would rather batch the bump separately, the upgrade script has to be renamed to whatever the next version is.

Checks

php-cs-fixer reports no diff, with a positive control returning 8 on an injected violation. php -l passes on PHP 7.2, the lowest leg of the syntax matrix, for all five touched PHP files. The before/after above is the substitute for a test: this module's suite is PHPStan only.

The product page swaps a few blocks over AJAX and pushes a new URL instead of
reloading, so displayFooterProduct never runs again: Google Analytics keeps
reporting the combination the page was opened with, whatever the shopper
switches to afterwards.

displayProductAdditionalInfo is one of the blocks that refresh returns, so
view_item is now sent from there for the newly selected combination. It is
emitted only for that refresh - a normal render still reports once, from
displayFooterProduct - and never for quickview, which has never reported.

ga_tag.tpl defers to DOMContentLoaded, which cannot fire again in an
already-loaded page, so the refreshed block uses a template without it.
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 this pull request may close these issues.

ps_googleanalytics allow for trackings hash in URL for product combinations

1 participant