TL;DR
Two questions get filed under the same heading and they have different answers. "Does my tracking work on Hyvä" is a compatibility question with a documented yes. "Does my tracking work on a headless or PWA storefront" is an architecture question, and the honest response from any Magento extension vendor is that a PHP module cannot emit a dataLayer into a JavaScript application it never renders. This article separates the two, explains which half of a tracking stack survives the move to headless and why, and gives you the questions to put to a vendor before you commit. Where this piece reasons from architecture rather than from documentation, it says so.
Key Takeaways
- Hyvä is not headless. It is a server-rendered Magento theme, which is why compatibility could be solved with modules rather than a rewrite:
weltpixel/module-hyva-ga4andweltpixel/module-hyva-ga4-csp, both PRO, both with no configuration options [1]. - A headless storefront talks to Magento over GraphQL and renders its own markup. The PHP layer that pushes ecommerce events into the dataLayer is not in that path.
- The WeltPixel GA4 documentation makes no headless or PWA Studio support claim [4], and that absence is the answer rather than an oversight [1].
- The server-side refund event originates from a Magento credit memo, not from the browser, which makes it the one clearly page-independent event in the stack [1]. The extension's other Measurement Protocol events, including item view, search, cart and checkout steps, are tied to storefront activity and inherit the same headless problem as the dataLayer.
- The server-side purchase is constructed on your server but documented as firing on the Magento Success Page, with a deliberate delay so the page finishes loading first [1]. A storefront that never renders that page cannot be assumed to fire it.
- The identifier problem is the real cost. A purchase event sent from the backend needs a GA4
client_idto join a session, and in a headless build nothing places that identifier in the browser unless you do. - Ask vendors whether their tracking has a frontend-independent path before you ask about features. Most answers to that question are short.
Hyvä is not a headless storefront
This confusion is worth clearing first, because it changes which of the two answers applies to you.
Hyvä replaces Magento's Luma frontend stack with Tailwind and Alpine.js, and it renders on the server through Magento's own layout and template system [3]. The page that arrives in the browser is still produced by PHP. That is why compatibility for a tracking extension could be delivered as two small modules rather than a new product: the extension still gets to emit its output into a rendered page, and the second covers the Hyvä CSP theme [1].
The install is composer require weltpixel/module-hyva-ga4 followed by composer require weltpixel/module-hyva-ga4-csp, then setup:upgrade, setup:di:compile, setup:static-content:deploy -f and cache:flush [1]. GA4 PRO must already be installed. The documentation states the addon has no configuration options and that the adjustments apply automatically once the modules are enabled [1]. Hyvä Checkout has its own compatibility on the PRO tier [1]. Our earlier write-up covers that case: GA4 compatibility with the Hyvä theme.
So if you are on Hyvä and someone told you that you need a headless tracking strategy, you were sold a problem you do not have.
What breaks when the frontend stops being PHP
A headless or PWA storefront inverts the arrangement. Magento becomes an API: the frontend application requests products, categories, cart state and checkout mutations over GraphQL [2], and renders whatever it likes with them, usually in React or Vue, often on a different host from the Magento instance itself.
Follow what that does to a client-side tracking module.
The module's job is to compute an ecommerce payload during page render and push it into window.dataLayer so a GTM container can pick it up. On a rendered Magento page, the product view template runs, the block computes item data, the script tag lands in the HTML. In a headless build, none of those templates execute for the shopper. The GraphQL response carries product data, but it carries the product data the frontend asked for, in Magento's API shape, with no ecommerce event wrapped around it and no dataLayer push attached.
The GTM container itself is not the obstacle. You can add a container snippet to a React application in an afternoon. What you cannot do is make a PHP module fill it, because the module is not in the render path. Every ecommerce event a headless storefront reports has to be constructed in the frontend code: view_item when the product route mounts, add_to_cart when the mutation resolves, begin_checkout at the first checkout step, and so on down GA4's recommended event list.
That is a real engineering scope, it belongs in the headless project plan, and it is routinely discovered after go-live instead.
Which half of your tracking survives?
Split the stack in two and the picture is clearer. What follows is reasoning from where each event originates, not a documented statement of headless support.
| Layer | Where it is produced | Effect of going headless |
|---|---|---|
| dataLayer ecommerce events | PHP templates and blocks | Not rendered; must be rebuilt in the frontend app |
| GTM container load | PHP head output | Must be added to the frontend app |
| Client-side ad platform pixels | GTM tags fed by the dataLayer | Depend on the rebuilt dataLayer |
| Other Measurement Protocol events (item view, search, cart, checkout steps, sign-up, login) | Storefront activity | Tied to the storefront; same problem as the dataLayer |
| Measurement Protocol purchase | Constructed server-side, documented as firing on the Magento Success Page | Cannot be assumed to fire if that page is never rendered |
| Refund events | Magento credit memo, admin-side | Triggered by the credit memo, not by a page |
The purchase row is the one to read carefully, because the intuition that server-side means page-independent does not survive the documentation. The payload is built on your server, but the event is documented as firing on the Success Page, with a deliberate delay so the page has time to load and the client-side Page View can fire first, and there is a Success Page Paths setting for checkouts that use a non-default path [1]. A storefront that never renders checkout/onepage/success is outside those assumptions, and confirming what actually happens is exactly what the staging test in the next section is for.
The refund event is the clean case. It originates from a credit memo created in the Magento admin, so no storefront is involved at any point [1].
Say it plainly before going further: the extension is documented against a rendered Magento storefront. A headless build is outside what the documentation covers, and nothing here should be read as a statement that it works. If your storefront does render through Magento, the full server-side mechanics are in our server-side tracking setup guide.
What a backend-originated purchase can and cannot carry
Here is the part that decides how useful the surviving half actually is.
GA4 joins events into sessions and attributes them to traffic sources using a client identifier, normally read from the _ga cookie in the browser. A purchase event sent from your server needs that identifier to land in the right session. When it has one, the order attaches to the acquisition history of that visitor. When it does not, the revenue is recorded and the attribution is not, which produces the familiar pattern of accurate totals sitting under unattributed traffic.
The extension has a documented setting for the adjacent problem: Client ID Fallback via gtag.js loads a lightweight gtag instance to retrieve the client_id from the Google tag when the _ga cookie is unavailable, for example under cookie restrictions or ad blockers [1]. Note the dependency, because it is the crux of the headless case. That fallback still needs a Google tag running in a browser. In a rendered Magento page the extension can put one there, if the fallback is enabled. In a headless application, placing it is your frontend team's job, and the identifier then has to reach your backend so the server-side event can carry it.
The same applies to the other context a server event lacks by default: page location, referrer, user agent, and the campaign parameters that were on the landing URL. On a rendered store the client side supplies these; in a headless build they exist only in the frontend app until someone passes them along.
What to verify before you commit
Take these to any vendor, ours included, and treat a vague answer as a no.
- Does the tracking have a path that does not depend on the storefront rendering, and which events use it?
- What identifier does a server-originated purchase carry, and how does that identifier get set in a frontend the vendor does not control?
- Is there documentation for a headless integration, or only for the rendered-theme case? Read what is written rather than what the sales page implies.
- How do consent signals from the frontend reach the server-side layer, given that the consent mechanism is typically part of the rendered page?
- Which client-side ad platform pixels do you actually need, and who is rebuilding their event triggers in the frontend?
- What does your staging environment show for a full test order, end to end, before launch rather than after?
Question 3 is the one that saves the most time. Documentation for a rendered-theme integration is not documentation for a headless one, and a vendor that has done headless work will have written it down.
FAQ
Does the WeltPixel GA4 extension support headless Magento storefronts?
The documentation makes no headless support claim, and none for Adobe's PWA Studio either [1][4]. It is documented against a rendered Magento storefront: client-side tracking depends on Magento rendering the page, and even the server-side purchase is documented as firing on the Success Page [1]. Test any assumption on staging before committing.
Is Hyvä affected by this?
No. Hyvä renders on the server through Magento's template system, and compatibility is handled by two PRO modules with no configuration options [1]. Hyvä Checkout is supported on the same tier [1].
Will my purchase events still reach GA4 from a headless store?
The documentation makes no headless support claim, so treat this as untested rather than covered [1]. The mechanism matters here: the Measurement Protocol purchase payload is built server-side, but the event is documented as firing on the Magento Success Page, with a delay so that page loads first [1]. A storefront that never renders it is outside those assumptions. Refunds are the clearer case, since they fire from an admin-side credit memo [1]. And even where a purchase does send, it needs a client identifier that a headless frontend has to supply, or the revenue lands unattributed.
What is the realistic scope of rebuilding client-side tracking in a PWA?
Every ecommerce event, individually: item views, list views, cart changes, checkout steps, and purchase, each fired from the right point in the application lifecycle and each carrying GA4's expected item parameters. Budget it as a workstream in the headless project rather than as a configuration task at the end.
If your storefront still renders through Magento, whether on Luma or on Hyvä, the WeltPixel Google Analytics 4 PRO extension covers both the dataLayer and the server-side layer, with the Hyvä modules installed alongside it.
And if you are still deciding on headless: run the test order on staging with your analytics team watching, before the migration date is announced rather than after.
Sources
- WeltPixel Google Analytics 4 User Guide, v1.17.3, August 3, 2026, https://docs.weltpixel.com/GA4/User-Guide-WeltPixel-Google-Analytics-4.html
- Adobe Commerce GraphQL developer documentation, https://developer.adobe.com/commerce/webapi/graphql/
- Hyvä Themes, https://www.hyva.io/
- Adobe Commerce PWA Studio developer documentation, https://developer.adobe.com/commerce/pwa-studio/