← Back to Blog

WordPress 6.8 Speculative Loading Is Firing GA4 and Meta Pixel Ghost Visits

WordPress 6.8, released April 15, 2025, merged speculative loading into core and enabled it by default for logged-out users on sites with pretty permalinks. In Chromium-based browsers, prefetched or prerendered pages can execute client-side JavaScript — including GA4 page_view events and Meta Pixel fires — before any visitor actually arrives. GA4 handles prerender natively by deferring measurement until activation, but custom GTM tags, Meta Pixel, and most third-party scripts do not. Server-side tracking avoids the problem entirely because the event fires on an actual server request, not a speculative browser render.

What Speculative Loading Actually Does

WordPress 6.8 uses the Speculation Rules API to prefetch or prerender internal pages before the visitor clicks, creating near-instant navigation in supported browsers.

When a logged-out visitor hovers over an internal link on a WordPress 6.8 site, the browser can begin loading that page in the background. The core default is prefetch with conservative eagerness — meaning the browser downloads the HTML response body milliseconds before the click, but does not fully render the page or execute its JavaScript. That distinction matters for analytics, but it gets blurry quickly.

The standalone Speculative Loading plugin, which ran on over 50,000 sites before the core merge, defaults to a more aggressive configuration: prerender with moderate eagerness. Prerendering goes further than prefetching. A prerendered page creates a full background rendering context — DOM, CSS, and JavaScript all execute as if the visitor had already arrived. The critical difference is that in a prerender scenario, every script on the target page runs before the visitor navigates.

The Speculation Rules API is currently supported in Chromium 121 and later, which covers Chrome, Edge, and Opera. In browsers that do not support it — Firefox and Safari — nothing changes. Pages load normally. No prefetching, no prerendering, no phantom analytics fires.

WordPress 6.8 applies speculative loading only to logged-out users on sites using pretty permalinks. Sites with heavy logged-in front-end traffic — WooCommerce stores, membership sites, forums — will not see it apply to authenticated sessions. But for any site where the majority of visits are anonymous browsing, the feature is on by default.

You may be interested in: Moving WooCommerce Tracking Server-Side? Your Purchases Are Showing Up as ‘(not set)’

WordPress 6.8 merged the Speculation Rules API into core and defaults to prefetch with conservative eagerness for all logged-out visitors on sites using pretty permalinks, affecting the majority of WordPress installations.

How Phantom Analytics Fires Happen

When a page is prerendered, JavaScript executes in a hidden context — and any analytics tag that fires on DOMContentLoaded or load without a prerender check will record a visit that never actually occurred.

The mechanics are straightforward. A visitor arrives on Page A. The browser, following WordPress’s speculation rules, begins prerendering Page B in the background. Page B’s JavaScript executes. If that JavaScript includes an analytics tag that fires a page_view event on load — without checking whether the page is actually being viewed — the analytics platform records a visit to Page B.

The visitor may never click through to Page B. They might navigate away entirely. But the event has already been sent. In GA4, that phantom page_view inflates session counts, distorts engagement rates, and corrupts landing page attribution. In Meta Events Manager, it creates a false signal that someone viewed a product page or browsed a category they never actually saw.

The browser provides two APIs to handle this correctly. The document.prerendering property returns true while the page is being prerendered. The prerenderingchange event fires when the prerendered page is activated — meaning the visitor actually navigated to it. Any analytics code that checks for document.prerendering and defers its initialization until the prerenderingchange event will avoid phantom fires.

The problem is that most third-party scripts do not perform this check. They were written before the Speculation Rules API existed, or before WordPress made speculative loading a default behavior. They fire on page load, period.

Prerendered pages execute JavaScript in a background rendering context — any analytics tag that fires on page load without checking document.prerendering will record a phantom visit that never happened.

Which Tools Handle Prerender and Which Do Not

GA4’s standard gtag.js is prerender-aware out of the box, but the majority of marketing tags loaded through GTM or injected by plugins are not.

Not all analytics tools are equally exposed. The split comes down to whether the vendor has updated their tag to respect the prerender lifecycle.

ToolPrerender-AwareNotes
GA4 (gtag.js)YesDelays page_view until prerenderingchange event fires automatically
Google Publisher TagYesDefers ad loading until activation
Google AdSenseYesDelays similarly to Google Publisher Tag
Meta Pixel (fbevents.js)NoFires PageView on load regardless of prerender state
Custom GTM tagsNo (unless modified)Fire on their configured triggers — typically page load or DOM ready
TikTok PixelNoFires on page load without prerender checks
Pinterest TagNoFires on page load without prerender checks
Hotjar / ClarityPartialSession recording may activate; heatmaps distorted

The distinction between prefetch and prerender matters here. Under WordPress 6.8’s core default (prefetch with conservative eagerness), JavaScript does not execute on the target page — only the HTML response body is downloaded. That means the core default alone does not cause phantom analytics fires. The risk escalates when a site owner installs the standalone Speculative Loading plugin and switches to prerender mode, or when a hosting provider or CDN configures more aggressive speculation.

But here is the subtlety that catches people. Even with prefetch only, if the browser decides to upgrade a prefetch to a prerender under certain conditions — which Chromium can do — the JavaScript execution risk returns. And WordPress plugin developers or themes that inject their own speculation rules can change the mode without the site owner realizing it.

You may be interested in: Your GA4 Is Blind to AI Traffic: How to Track ChatGPT, Claude and Perplexity Visitors

Fixing Client-Side Tags for Prerender

The fix for client-side tags involves wrapping analytics initialization in a prerender check — a pattern documented by Chrome DevRel and MDN but rarely implemented in practice.

The recommended pattern wraps your analytics or tag manager initialization in a promise that resolves either immediately (on a normal page load) or after the prerenderingchange event fires (on a prerendered page). This ensures that no measurement code executes until the visitor has actually navigated to the page.

The approach works for Google Tag Manager, Meta Pixel, and any script loaded via a tag manager. Instead of loading GTM or Meta Pixel directly in the page head, you defer it behind the prerender gate. The pattern creates a constant that holds a promise. If the page is currently being prerendered, the promise waits for the prerenderingchange event. If the page is not being prerendered, the promise resolves immediately.

This works. But it introduces complexity. Every tag loaded through GTM inherits whatever trigger configuration the marketer set — page load, DOM ready, custom event. Wrapping the entire GTM container in a prerender gate means every tag in the container defers, which is the safest approach but requires understanding the trade-off: tags that need to fire before interaction (consent banners, for example) will also be delayed on prerendered pages.

WordPress developers can also use the wp_speculation_rules_href_exclude_paths filter to exclude specific URL patterns from speculative loading entirely. If you have a checkout page, a thank-you page, or any dynamic endpoint where prerendering would cause problems, exclusion is the more surgical option.

For individual links, adding the CSS class no-prefetch or no-prerender to an anchor element tells WordPress to skip speculation for that link.

The Server-Side Alternative

Server-side tracking removes the prerender problem at the infrastructure level — the event fires when an actual server request occurs, not when the browser speculatively renders a page.

The cleanest solution to speculative loading’s analytics side effects is to move the measurement point from the browser to the server. When your tracking fires on a server-side event — an actual HTTP request, a form submission webhook, a purchase confirmation — there is no prerender lifecycle to manage. The browser can speculatively render as many pages as it wants. Your analytics only records what actually happened.

This is the structural argument for server-side tracking that predates WordPress 6.8 but becomes sharper with it. Client-side tags have always been fragile. Ad blockers strip them. Safari ITP limits their cookies to seven days. Consent banners suppress them. Now speculative loading adds another failure mode: phantom fires that inflate rather than deflate your numbers.

A server-side event pipeline captures the conversion at the source — the server — and routes it to GA4, Meta, and other platforms via their measurement APIs. The Transmute Engine™ does this for WordPress and WooCommerce stores by hooking server-side events and forwarding them to each platform’s server API with full attribution data. No prerender check needed. No GTM wrapper. No phantom fires.

Translation: the browser is becoming an unreliable measurement point. Speculative loading is just the latest reason. The durable answer is not to patch every client-side tag for every new browser behavior — it is to stop depending on the browser for measurement in the first place.

Server-side tracking records the event when an actual server request occurs, not when the browser speculatively renders a page — eliminating phantom analytics fires at the infrastructure level.

Key Takeaways

  • WordPress 6.8 enabled speculative loading by default: All logged-out visitors on sites with pretty permalinks now trigger prefetching of internal links in Chromium browsers — a change that affects the majority of WordPress installations.
  • Prerendered pages can fire analytics events prematurely: Any script that initializes on page load without checking document.prerendering will record phantom visits, inflating traffic numbers and distorting engagement metrics.
  • GA4 is safe by default, but most other tools are not: GA4’s gtag.js defers measurement until activation, but Meta Pixel, TikTok Pixel, Pinterest Tag, and custom GTM tags fire without prerender checks.
  • Client-side fixes exist but add complexity: Wrapping tag initialization in a prerenderingchange gate works, but requires modifying how every non-prerender-aware script loads across your site.
  • Server-side tracking eliminates the problem structurally: When measurement fires on the server rather than in the browser, speculative loading, ad blockers, and consent banners all become irrelevant to data accuracy.
Did WordPress 6.8 change my analytics numbers?

It can. If your analytics tags fire on page load without checking document.prerendering, prefetched or prerendered pages will record phantom visits in Chromium browsers. GA4’s gtag.js already defers to activation, but custom GTM tags and most third-party pixels do not.

How do I exclude links from prefetch or prerender in WordPress?

Add the no-prefetch or no-prerender CSS class to specific anchor elements, or use the wp_speculation_rules_href_exclude_paths filter in your theme’s functions.php to exclude URL patterns site-wide.

Does GA4 already handle prerender correctly?

GA4’s standard gtag.js snippet delays page_view measurement until the prerenderingchange event fires, so its default implementation is prerender-aware. However, any custom event tags in GTM or additional scripts loaded alongside GA4 may still fire prematurely.

How does server-side tracking avoid this problem?

A server-side event fires when the actual HTTP request hits the server or when a real user action triggers a webhook — not when the browser speculatively renders a page in the background. There is no prerender lifecycle to manage because the event source is the server, not the client.

Should I disable speculative loading entirely?

Not necessarily. The performance benefits are real — near-instant page transitions in Chromium browsers. The better approach is to ensure your analytics tags are prerender-aware rather than disabling the feature. If you use only GA4 with standard gtag.js, you are likely already safe.

References

If your WordPress site runs GA4, Meta Pixel, or any custom tracking through GTM, a 15-minute audit can tell you whether speculative loading is inflating your numbers — and what it takes to fix it.