Reviewed June 2026. Universal Analytics stopped processing data in July 2023 (GA4 is the only version); Consent Mode v2 has been required for EEA Google Ads features since March 2024. Code below targets PrestaShop 1.7, 8 and 9.

Here is the gap that catches most PrestaShop merchants out: installing a Google Analytics 4 module is not the same as having GA4 set up. You drop in a Measurement ID, you see "users" climbing in the Realtime report, and it looks done. Then six weeks later you open Monetization → Ecommerce purchases to work out which products actually sell, and the report is empty, or worse, it shows half your revenue because the purchase event only fires sometimes. A page-view counter is trivial to install. A GA4 property that records every product view, every add-to-cart, every abandoned checkout step, and every completed order with the right transaction total. That takes deliberate setup, and that is what this guide is about.

This is the complete, PrestaShop-specific setup walkthrough: creating the property, choosing an installation method that fits your store, wiring up ecommerce events, getting consent handling right for the EU, and, the part everyone skips, verifying that the data arriving in GA4 is actually correct. Once the plumbing is in place and trustworthy, the question becomes which numbers to act on; that is a separate discipline, and we cover it in the metrics that actually matter. This post gets you a setup worth reading in the first place.

Before you start: one property, the right data stream

GA4 has been the only version since Universal Analytics stopped processing data in July 2023, so if you are migrating from a UA setup, none of your old configuration carries over. GA4 is a different measurement model (events, not sessions) and needs building from scratch. Create the property first, then install on PrestaShop. Doing it the other way round is how stores end up with two half-configured properties and tracking split between them.

Create the GA4 property

  • In Google Analytics, go to Admin → Create → Property (the gear icon, bottom left).
  • Enter your store name, then set the reporting time zone and currency to match your PrestaShop store. This matters more than it looks: your property currency should match your store currency unless your integration sends the correct currency on every ecommerce event, otherwise revenue figures in GA4 can be wrong, and there is no retroactive fix, since GA4 does not reprocess historical data.
  • Under the property, create a Web data stream and enter your store's full URL (with or without www exactly as your canonical domain resolves).
  • Copy the Measurement ID. It starts with G-. This is the only thing your PrestaShop module needs.

One data stream per platform is the rule. A normal PrestaShop store is a single website, so you need exactly one web stream. Resist the temptation to create a second stream "for testing". Use a separate property for that, or you will mix staging traffic into your real reports.

Three ways to get GA4 onto PrestaShop

PrestaShop does not put GA4 in core, so you choose how the Google tag gets injected and how ecommerce data reaches it. The three routes differ mostly in how much ecommerce depth you get out of the box versus how much you assemble yourself.

MethodEffort to set upEcommerce events out of the boxBest when…
ps_googleanalytics (PrestaShop's bundled module)Low, paste the Measurement IDBasic; some events partial or missing product dataYou need pageviews and a rough revenue figure, fast, and will refine later.
Google Tag ManagerHigh, install container, build a data layer yourselfNone until you configure tags + triggersYou want to manage many tags (Ads, Meta, GA4) from one place without code edits.
Dedicated GA4 module (e.g. our mprgoogleanalytics)Low, install & configure from back officeComplete recommended event set with full product data + Consent Mode v2You want every ecommerce report populated correctly without building the data layer by hand.

Option A, the bundled ps_googleanalytics module

PrestaShop ships an official Google Analytics module. Install it from Modules → Module Manager (search "Google Analytics"), open its configuration, and paste your G- Measurement ID. GA4 support arrived in ps_googleanalytics v4 (the older releases that shipped with PrestaShop 1.6 and early 1.7 only spoke Universal Analytics), so make sure the module is up to date first, use a current GA4-compatible version and check the module's compatibility for your PrestaShop version. Once updated, it injects the Google tag (gtag.js) and fires basic ecommerce events through PrestaShop's hooks. So what's the catch? Its ecommerce coverage is partial, depending on your theme and version, events like view_item_list may not fire, and product objects can arrive missing category or brand. It is genuinely fine for "is the store getting traffic and roughly how much revenue," and a reasonable starting point. It is not enough if you intend to make catalog or checkout decisions from the data.

Option B, Google Tag Manager

GTM gives you a single container to manage every marketing tag without redeploying code, which is its real appeal once you are running GA4 plus Google Ads plus a Meta pixel. The trade-off is that GTM ships nothing for ecommerce until you build a data layer and wire up triggers. Work that, on PrestaShop, means getting structured product and order data into window.dataLayer at the right moments. If GTM is the route you want, we walk through installing the container and setting up tracking without code edits in the GTM for PrestaShop guide, follow that, then point a GA4 configuration tag at the Measurement ID from this guide.

Option C, a dedicated GA4 module

A purpose-built module exists precisely to remove the data-layer assembly work. Our mprgoogleanalytics module hooks into PrestaShop's catalog, cart and order events directly and emits the full recommended GA4 ecommerce event set with complete product parameters, plus Google Consent Mode v2 and a built-in debugging view. What that means in practice: the Monetization reports below populate correctly the day you install it, without you hand-coding a single dataLayer.push, you configure it from the back office, paste the Measurement ID, set your consent integration, and the ecommerce funnel just fills in. It installs cleanly from Module Manager and survives upgrades because it works through hooks rather than theme edits.

The ecommerce events your setup must fire

This is where most PrestaShop GA4 installs quietly fall short, so it is worth knowing the target. GA4's ecommerce reports are driven by a specific set of recommended events. Whatever method you chose above, a strong ecommerce setup should fire the relevant recommended events for the reports you need, each at the correct point in the customer journey:

  • view_item_list, on category pages and search results (the array of products shown).
  • view_item, on a product page.
  • add_to_cart / remove_from_cart, when the cart changes.
  • view_cart, on the cart page.
  • begin_checkout, when the customer enters the order controller.
  • add_shipping_info, when a carrier is selected.
  • add_payment_info, when a payment method is chosen.
  • purchase, on order confirmation. The single most important event, and the one most often broken.

The purchase event must carry the transaction ID, total value, tax, shipping cost, currency, and an array of every purchased item. If any of those is missing or wrong, your revenue reporting is wrong. And the events are only as useful as the product data inside them. Each item should include item_id, item_name, price (after discount), quantity, item_category, item_brand and item_variant (the selected combination). A setup that sends only IDs and prices technically "works" but throws away the category, brand and variant analysis that makes the reports worth opening.

Here is the shape that purchase push should take on the order-confirmation page. The values come from PrestaShop's own order object, $order->reference for the transaction ID, $order->total_paid, $order->total_paid_tax_incl/_tax_excl for tax, $order->total_shipping, the order's currency ISO code, and the product line items, rendered into the template (escape every value):

<!-- order-confirmation page, after the order is confirmed -->
<script>
  window.dataLayer = window.dataLayer || [];
  // Guard: fire purchase only once per order. Keyed on the order reference,
  // so reloading the confirmation page can't double-count the sale.
  var gaTxnKey = 'ga4_purchase_{$order.reference|escape:'javascript'}';
  if (!localStorage.getItem(gaTxnKey)) {ldelim}
    localStorage.setItem(gaTxnKey, '1');
    // Clear any previous ecommerce object so item data can't leak between events
    dataLayer.push({ ecommerce: null });
    dataLayer.push({
      event: 'purchase',
      ecommerce: {
        transaction_id: '{$order.reference}',          // e.g. "XKBKNABJK"
        value: {$order.total_paid|floatval},            // total incl. tax
        // No $order->total_tax property exists – derive tax from the
        // incl./excl. totals (or pass a precomputed, escaped variable).
        tax: {($order.total_paid_tax_incl - $order.total_paid_tax_excl)|floatval},
        shipping: {$order.total_shipping|floatval},
        currency: '{$currency.iso_code}',               // e.g. "EUR"
        items: [
          {foreach $products as $p}
          {ldelim}
            item_id: '{$p.reference}',
            item_name: '{$p.name|escape:'javascript'}',
            price: {$p.price_amount|floatval},
            quantity: {$p.quantity|intval}
          {rdelim}{if !$p@last},{/if}
          {/foreach}
        ]
      }
    });
  {rdelim}
</script>

Two non-negotiables in that block: the dataLayer.push({ ecommerce: null }) reset above it (without it, item data from an earlier event leaks in), and a guard so it fires only once per order, keyed on the transaction reference, so a customer reloading the confirmation page can't double-count the sale. This is exactly the wiring a dedicated module does for you from PrestaShop's hooks instead of in template files.

The two data-layer details that catch people out

If you are building the data layer yourself (Option B, or any custom work), two specifics cause most of the broken setups we see:

  • Clear the ecommerce object between events. Push { ecommerce: null } before each new ecommerce event, otherwise product data from the previous event leaks into the next one and your item arrays become nonsense.
  • Hook the AJAX add-to-cart, not just page load. Most PrestaShop themes add to cart over AJAX without a page reload. If your tracking only listens on page load, add_to_cart never fires, a classic silent gap where the report simply shows nothing and nobody notices for weeks.

Since March 2024, Google requires Consent Mode v2 if you use Google Ads remarketing or conversion measurement features with visitors in the European Economic Area. Without it you lose remarketing audiences and conversion modeling for those users. Consent Mode v2 is not itself a substitute for GDPR compliance, though. Cookie consent and a proper legal basis still need a dedicated CMP. For an EU-facing store running Google advertising features, there is no way around it.

The correct flow is: the default consent state is denied for the applicable signals, analytics_storage, ad_storage, and, for advertising use cases, ad_user_data and ad_personalization; when the visitor accepts cookies, you update the relevant signals to granted and GA4 begins full tracking. On a denied state, GA4 does not go dark, it sends cookieless pings that Google uses for modeled data, with no user-identifying storage.

The order matters: the default consent command must run before the gtag config and before any tag that reads consent, so the very first hit already respects it. In a hand-rolled setup the head snippet looks like this (your CMP later calls gtag('consent', 'update', …) when the visitor accepts):

<!-- Google tag (gtag.js) – in <head>, before any other GA/Ads tag -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  // Consent Mode v2 – default denied until the CMP says otherwise (EEA)
  gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied',
    'wait_for_update': 500
  });

  gtag('config', 'G-XXXXXXXXXX');
</script>

Then, when the visitor accepts in your cookie banner, the CMP grants the categories they agreed to:

gtag('consent', 'update', {
  'analytics_storage': 'granted',
  'ad_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted'
});

A module with native Consent Mode v2 wires this for you so you never hand-place the snippet or risk getting the order wrong. Your GA4 setup has to talk to whatever consent layer you run, your cookie/GDPR module or a third-party CMP like Cookiebot or Axeptio (PrestaShop core does not ship a full cookie-consent system by default). If your module cannot integrate with your consent tool, you are forced to choose between tracking without consent (a GDPR problem) or blocking GA4 entirely until consent (losing most of your data). A module with native Consent Mode v2 support, like mprgoogleanalytics, exists to keep you out of that bind. For a fuller comparison of where GA4 sits against a consent-first alternative, see Matomo vs Google Analytics.

Verify the setup, don't trust "it looks like it's working"

Google Analytics 4 diagnostics screen in the PrestaShop back office listing hook order, consent mode and configuration checks with pass and warning results
The GA4 diagnostics screen in the back office checks hook order, consent integration and the measurement ID, so you verify the setup instead of guessing it works.

A GA4 install can send incomplete or duplicated data while looking perfectly healthy in the Realtime card. Verification is the step that separates a real setup from a hopeful one, and it takes ten minutes.

Realtime, then DebugView

  • Quick smoke test: open your store, then in GA4 go to Reports → Realtime. Your visit should appear within seconds. If it does not, the tag is not loading, re-check the Measurement ID.
  • Network check: open browser DevTools (F12) → Network, filter by collect, and confirm requests to google-analytics.com/g/collect as you browse.
  • The real test, DebugView: open Admin → DebugView in GA4 (to populate it, enable debug mode, use Google Tag Assistant, the Google Analytics Debugger Chrome extension, GTM preview mode, or explicitly send debug_mode=true; opening DevTools alone does not turn it on). Now walk your own store as a customer would: view a category, open a product, add to cart, start checkout, place a test order. Watch each event appear with its parameters. Does view_item fire on the product page? Does add_to_cart fire on the AJAX add? Does purchase fire once on the confirmation page with the right total and items?

Google's Tag Assistant (tagassistant.google.com) is the second opinion, it shows every Google tag firing and flags configuration issues you might miss in DebugView.

The four failures to look for specifically

  • Purchase fires twice. If a customer reloads the order-confirmation page, the event can fire again and inflate revenue. A correct setup guards against this by checking whether that transaction ID was already sent.
  • Null categories or brands. Products show up in events but with empty item_category / item_brand, the integration isn't pulling full product data from the PrestaShop database.
  • Currency mismatch. The event sends a EUR price but a USD currency parameter (or vice versa), skewing every revenue report. Usually traces back to the property/store currency mismatch from the first section.
  • Nothing on AJAX cart. As above, add_to_cart silently never fires because the listener missed the AJAX path.

Filter your own traffic out before you trust the numbers

Your visits and your team's visits inflate engagement and pollute conversion data, and during setup you generate a lot of test traffic. Define it as internal so GA4 can exclude it: go to Admin → Data Streams → [your web stream] → Configure tag settings → Show all → Define internal traffic, and add your office and home IP addresses. Then under Admin → Data Settings → Data Filters, confirm the "Internal Traffic" filter is set to Active (it ships in Testing mode and does nothing until you activate it, a step almost everyone forgets). GA4 already excludes known bots and spiders automatically, but if you are still seeing odd patterns, suspicious traffic needs investigating, possibly with server, CMP or tagging controls rather than a single switch; for the specific case of Google's own crawler adding items to carts, see Google Storebot is shopping in your store.

Where to look once data is flowing

With events firing correctly, the ecommerce-specific reports become useful. The three that justify the whole setup live under Reports → Monetization:

  • Ecommerce purchases, revenue and units by product, category and brand. Empty here means your purchase event or product data is broken.
  • Purchase journey, the funnel from view_item through to purchase, with drop-off at each stage.
  • Checkout journey, the detailed funnel through begin_checkout, add_shipping_info and add_payment_info. A missing begin_checkout leaves this funnel with no starting point, which is the most common reason it looks blank.

These reports only work because the events behind them fire correctly. Which is the entire reason verification came first. Reading them well, knowing which numbers signal a real problem and which are noise, is its own skill; we cover GA4 interpretation in the metrics that actually matter, and the broader question of what is worth tracking at all in what to track and what to ignore.

Once GA4 is solid, a few links open up more. From Admin → Product Links you can connect Google Ads (import GA4 conversions, build remarketing audiences), Search Console (organic search terms next to behavior), Merchant Center (product-level performance), and BigQuery (raw event export, free tier available) for analysis GA4's interface can't do.

One honest limit: GA4 is not your revenue source of truth

Set GA4 up properly and it is excellent for understanding behavior. The path customers take, where they drop, which products draw views that don't convert. But GA4 can be affected by sampling in Explorations and by thresholding and cardinality limits, loses data to consent denials, and processes with a delay, which makes it the wrong tool to be your final word on revenue. Keep revenue truth in PrestaShop and your orders. Use your PrestaShop order data and your payment processor's reports as the source of truth for money, and GA4 for the why behind it. If you want reporting built on your actual store database rather than sampled analytics, our Financial Revolution reporting module reads straight from PrestaShop and reconciles to the cent.

Beyond the numbers: see what people actually do

GA4 tells you what happened and how many. It does not show you a customer hesitating over a confusing shipping selector or rage-clicking a button that doesn't respond. For that qualitative layer, pair GA4 with session recordings and heatmaps: Microsoft Clarity (free) or Hotjar turn a GA4 drop-off on the checkout funnel into a video of why it happened.

Frequently asked questions

Do I lose my Universal Analytics history when I move to GA4?

Effectively, yes. Universal Analytics stopped processing new data in July 2023 and Google has been shutting down access to the old reports, so GA4 starts from zero on the day you install it. There is no migration of historical sessions, because GA4 uses a different, event-based model. Set GA4 up sooner rather than later so it accumulates the history you'll want next year, and export anything you still need from UA while you can.

Can I run ps_googleanalytics and a GTM-based GA4 tag at the same time?

No, that double-counts every pageview and every purchase against the same property, which inflates revenue and breaks your conversion rates. Pick one path: either the module owns GA4, or GTM does. If you switch to GTM, disable the GA module in Module Manager and verify in DebugView that each action appears exactly once.

Why is my purchase value right but the currency wrong in GA4?

That's almost always the property/store currency mismatch from the first section, or a purchase push that hard-codes a currency instead of reading $currency.iso_code from the order. GA4 does not reprocess historical data, so a wrong-currency stretch can't be fixed retroactively. Set the property currency to match your store and send the real per-order ISO code on every event.

No. Consent Mode v2 is the mechanism Google's tags use to read consent signals; it is required since March 2024 for EEA Google Ads features, but it is not itself a consent management platform. You still need a real CMP (a cookie module or a Google-certified banner) to collect and store the legal basis. PrestaShop core does not ship one. Consent Mode tells Google what the visitor chose; the CMP is what actually asks them.

My add_to_cart never fires, what's wrong?

Most PrestaShop themes add to cart over AJAX with no page reload, so tracking that only listens on page load never sees it. The event has to hook the AJAX add-to-cart response (the same call the cart controller handles). This is one of the silent gaps that leaves a funnel blank in the middle, confirm it in DebugView by adding to cart and watching for the event, and if you'd rather not hand-wire it, a module such as mprgoogleanalytics fires it from the cart hook.

The short version

A complete GA4 setup on PrestaShop is four jobs done in order: create one property with the right currency and time zone; choose an installation method that fires the full ecommerce event set; integrate Consent Mode v2 so you track legally in the EU; and verify in DebugView that every event arrives with correct, complete data before you trust a single report. Skip the verification and you have a page-view counter wearing an analytics costume. Do it properly, or install a module that does the ecommerce and consent plumbing for you, like mprgoogleanalytics, and you get the funnel, the product-level revenue, and the behavioral picture that actually informs decisions.

David Miller

David Miller

Founder, mypresta.rocks
About the author

David Miller is a PrestaShop specialist with over a decade of hands-on experience and the founder of mypresta.rocks, a software studio in Tychy, Poland. He builds and maintains a catalogue of 152 PrestaShop modules, including 21 "Revolution" suites spanning SEO, checkout, security, performance, marketing, search, support, and warehouse operations, that improve real stores every day, all tested against PrestaShop 1.7.8, 8.x, and 9.x. He also acts as caretaker for production stores turning over millions in annual sales, so his work is judged on live revenue, not demos. His experience runs the full breadth of ecommerce, performance, security, SEO, and marketing, and reaches beyond PrestaShop to WooCommerce, Shopify, and custom-built systems. On the blog he writes about the code-aware side of PrestaShop: what the platform really does under the hood, what breaks in production, and which fixes hold up.

Share this post:

Comments

No comments yet. Be the first!

Enjoyed this article?

Get our latest tips, guides and module updates delivered to your inbox.

You may unsubscribe at any moment. For that purpose, please find our contact info in the legal notice.

Loading...
Back to top