WooCommerce GA4 purchase tracking without MonsterInsights: a plugin you can build today

· 5 min read

MonsterInsights is the default answer to adding Google Analytics to WooCommerce. It works, but it is a heavy plugin with a database footprint, a paid tier behind most of the useful settings, and far more configuration than most stores need. The core job it does is narrow: inject the GA4 snippet and tell Google when an order completes.

GA4 ecommerce tracking requires a specific event shape. A generic analytics snippet or copy-pasted gtag tag does not automatically fire the purchase event with order data. MonsterInsights hooks into WooCommerce's thank-you page and sends the right fields. A small purpose-built plugin can do the same thing in a few dozen lines of PHP.

The plugin described here adds a single field to WooCommerce settings for your GA4 Measurement ID. It injects gtag.js on every page and fires a purchase event on the thank-you page, with order value, currency, tax, shipping, and a line-item array. That is the whole plugin.

What one build gives you

  • A settings field in WooCommerce > Settings > General for your GA4 Measurement ID
  • gtag.js injected on every page using the configured Measurement ID
  • A purchase event on the WooCommerce thank-you page with transaction_id, value, currency, tax, shipping, and a per-line-item array
  • Line items include product name, SKU or product ID, unit price, and quantity
  • No admin menu, no dashboard widget, no stylesheet

What it does not do

  • Upper funnel events: view_item, add_to_cart, and begin_checkout require a follow-up prompt
  • Server-side tracking via the Measurement Protocol; browser ad blockers can still intercept the event
  • GA4 reports embedded inside the WordPress admin dashboard
  • Google Tag Manager integration; GTM handles its own snippet injection separately
  • Automatic deduplication if a caching plugin serves a static thank-you page that bypasses the PHP hook

MonsterInsights does these. This covers the part most sites use.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin that adds lightweight GA4 purchase tracking to WooCommerce. Plugin Name: WC GA4 Purchase Tracking. Version: 1.0.0. Description: Fires a GA4 purchase event on WooCommerce order completion. Wrap all code in a function attached to plugins_loaded. Add a settings field using the woocommerce_general_settings filter: prepend an array element with type 'text', id 'wc_ga4_measurement_id', title 'GA4 Measurement ID', desc 'Your GA4 Measurement ID (G-XXXXXXXXXX)', default '', desc_tip true. On wp_head at priority 1, read get_option('wc_ga4_measurement_id') into $mid; if not empty, esc_attr it and echo: a script tag with async src https://www.googletagmanager.com/gtag/js?id={$mid}, then an inline script that declares window.dataLayer=window.dataLayer||[], a function gtag(){dataLayer.push(arguments);}, then calls gtag('js',new Date()) and gtag('config','{$mid}'). On the woocommerce_thankyou action, which receives $order_id, get the order with wc_get_order($order_id); if the order exists and get_option('wc_ga4_measurement_id') is not empty, build a PHP array $items by iterating $order->get_items(): for each WC_Order_Item_Product, get the product with $item->get_product(); push an associative array with keys item_name (esc_js($item->get_name())), item_id (esc_js($product && $product->get_sku() ? $product->get_sku() : (string)$item->get_product_id())), price ($item->get_quantity()>0 ? round((float)$item->get_subtotal()/$item->get_quantity(),2) : 0.0), quantity (intval($item->get_quantity())). Then echo an inline script that pushes to window.dataLayer: an object with event 'purchase' and ecommerce containing transaction_id (esc_js($order->get_order_number())), value (floatval($order->get_total())), currency (esc_attr($order->get_currency())), tax (floatval($order->get_total_tax())), shipping (floatval($order->get_shipping_total())), items (wp_json_encode($items) output raw inside the script). Use proper escaping throughout. No admin menu, no options page beyond the WooCommerce settings field, no stylesheet.

Build this pluginAbout 55 credits · the free plan includes enough for one

What the plugin tracks

The plugin fires one GA4 event: purchase, on the WooCommerce order confirmation page. GA4 receives the transaction ID, order total, currency, tax amount, shipping cost, and an items array with one entry per line item. Each item includes the product name, SKU (falling back to the product ID if no SKU is set), unit price, and quantity.

The data comes from the WooCommerce order object, so it matches what is stored in your database exactly. The thank-you page is shown once per order, which means the event fires once. If a customer refreshes the page, the event fires again, but that is a limitation of client-side tracking in general and not specific to this plugin.

A single settings field appears in WooCommerce > Settings > General. Paste your G-XXXXXXXXXX Measurement ID there and save. No options page, no admin menu, no dashboard widget.

What it leaves out

Upper funnel events such as view_item, add_to_cart, and begin_checkout are not included. Without them, the GA4 purchase funnel report will show only the final conversion step. If you need full funnel data, the follow-up message in the next section extends the plugin with add_to_cart tracking.

There is no Measurement Protocol or server-side tracking. The purchase event is fired by gtag.js in the browser. Ad blockers that intercept Google's scripts will drop the event for those users. For most stores this is an acceptable trade-off; for stores where measurement accuracy is critical, server-side tracking via the Measurement Protocol is a separate build.

There are no GA4 reports inside the WordPress dashboard. You open GA4 directly to see your data. If seeing reports without leaving WordPress is a requirement, keep MonsterInsights.

When to keep MonsterInsights

A client who needs to see GA4 reports inside the WordPress admin without logging into Google Analytics should keep MonsterInsights. That embedded reporting is its strongest feature and not something a simple tracking plugin replicates.

If you are already paying for MonsterInsights Pro for another reason, adding WooCommerce tracking is a settings toggle. The cost is already sunk. This plugin is for stores where the subscription is the only reason MonsterInsights is installed.

MonsterInsights also handles the full enhanced ecommerce event set through a checkbox interface. If a non-developer needs to configure add-to-cart or checkout funnel tracking without editing code, that configuration experience is worth paying for.

How to build it

Paste the prompt below into Steem. Once the plugin is active, go to WooCommerce > Settings > General, scroll down to the GA4 Measurement ID field, enter your G-XXXXXXXXXX, and save. Place a test order, then open GA4 and go to Reports > Realtime. The purchase event should appear within a few seconds of completing the order.

If you also need add_to_cart tracking, the follow-up message is: 'Add an add_to_cart event to the GA4 plugin. On the woocommerce_add_to_cart action, which receives cart_item_key, product_id, quantity and variation_id, get the product with wc_get_product using product_id. If the measurement ID option is set and the product exists, output an inline script that pushes to window.dataLayer: event add_to_cart, ecommerce.items array with one item: item_name (esc_js of product name), item_id (esc_js of SKU or string of product_id if no SKU), price (floatval of get_price()), quantity (intval of quantity passed to hook). Use wp_json_encode for the items array.'

Questions

Do I need to set up a GA4 property first?

Yes. Create the property in Google Analytics, then go to Admin > Data Streams, select your web stream, and copy the Measurement ID. It starts with G-. Paste that into the plugin's settings field.

Will I see full funnel data in GA4?

No, only the final purchase step. GA4's purchase funnel report also expects add_to_cart and begin_checkout events. Without those, the funnel shows only conversions. Use the follow-up prompt in the guide to add add_to_cart tracking.

Why is the purchase event not appearing in GA4 Realtime?

Three common causes: a typo in the Measurement ID, an ad blocker or privacy extension intercepting gtag.js, or a caching plugin serving a static copy of the thank-you page that does not execute the PHP hook. Test in an incognito window on an uncached URL.

Can I use this alongside Google Tag Manager?

Not directly. GTM handles its own gtag injection, and running two conflicting gtag configurations causes duplicate events. If you are using GTM, configure the purchase event as a dataLayer push inside GTM instead of using this plugin.

Does this work with WooCommerce High-Performance Order Storage?

Yes. The woocommerce_thankyou hook receives a plain order ID and the plugin fetches the order with wc_get_order, which supports both the legacy post-based storage and HPOS.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin that adds lightweight GA4 purchase tracking to WooCommerce. Plugin Name: WC GA4 Purchase Tracking. Version: 1.0.0. Description: Fires a GA4 purchase event on WooCommerce order completion. Wrap all code in a function attached to plugins_loaded. Add a settings field using the woocommerce_general_settings filter: prepend an array element with type 'text', id 'wc_ga4_measurement_id', title 'GA4 Measurement ID', desc 'Your GA4 Measurement ID (G-XXXXXXXXXX)', default '', desc_tip true. On wp_head at priority 1, read get_option('wc_ga4_measurement_id') into $mid; if not empty, esc_attr it and echo: a script tag with async src https://www.googletagmanager.com/gtag/js?id={$mid}, then an inline script that declares window.dataLayer=window.dataLayer||[], a function gtag(){dataLayer.push(arguments);}, then calls gtag('js',new Date()) and gtag('config','{$mid}'). On the woocommerce_thankyou action, which receives $order_id, get the order with wc_get_order($order_id); if the order exists and get_option('wc_ga4_measurement_id') is not empty, build a PHP array $items by iterating $order->get_items(): for each WC_Order_Item_Product, get the product with $item->get_product(); push an associative array with keys item_name (esc_js($item->get_name())), item_id (esc_js($product && $product->get_sku() ? $product->get_sku() : (string)$item->get_product_id())), price ($item->get_quantity()>0 ? round((float)$item->get_subtotal()/$item->get_quantity(),2) : 0.0), quantity (intval($item->get_quantity())). Then echo an inline script that pushes to window.dataLayer: an object with event 'purchase' and ecommerce containing transaction_id (esc_js($order->get_order_number())), value (floatval($order->get_total())), currency (esc_attr($order->get_currency())), tax (floatval($order->get_total_tax())), shipping (floatval($order->get_shipping_total())), items (wp_json_encode($items) output raw inside the script). Use proper escaping throughout. No admin menu, no options page beyond the WooCommerce settings field, no stylesheet.

Build this pluginAbout 55 credits · the free plan includes enough for one

Read next

Other plugins you can build this way

Each loads into the composer, ready to edit.