Skip to content

Stop reporting PageView on 404 responses - #4057

Open
vahidkay-meta wants to merge 2 commits into
mainfrom
fix/no-pageview-on-404
Open

vahidkay-meta wants to merge 2 commits into
mainfrom
fix/no-pageview-on-404

Conversation

@vahidkay-meta

Copy link
Copy Markdown
Contributor

Description

Every 404 response reports a PageView. WordPress renders its 404 template for any URL it cannot resolve, and the default rewrite rules route requests for missing files through index.php as well as mistyped URLs — so wp_head runs, and inject_base_pixel() fires a PageView for a URL that does not exist.

Three things reported it:

  • the CAPI event from inject_page_view_event()
  • the client-side fbq track from the same method
  • the <noscript> image, which requests ev=PageView&noscript=1

Surfaced by #4054, where a missing JavaScript file was producing page views of itself, but it applies to any bad URL on the store: broken links, crawlers probing paths, an image deleted from the uploads folder.

The fix

A single should_report_page_view() check, used by the PageView event and the noscript block.

The base pixel code still prints on a 404. pixel_base_code() only runs fbq('init', ...) — it reports nothing by itself — so keeping it leaves window.fbq defined for anything else on the page while the actual PageView goes away.

Other events are untouched. They are bound to WooCommerce template hooks that a 404 does not reach.

Restoring the old behaviour

Stores that deliberately track 404s can filter it back on:

add_filter( 'wc_facebook_should_report_page_view', '__return_true' );

The filter receives the current decision, so it can also be used to suppress PageView on other responses.

Testing

In FacebookCommerceEventsTrackerTest: nothing is tracked on a 404; an ordinary page still tracks exactly one PageView (the control, so the first test cannot pass vacuously); the filter restores it; and the noscript block prints ev=PageView on an ordinary page but nothing on a 404. That last one resets WC_Facebookcommerce_Pixel::$render_cache around itself, since the block renders at most once per request and a leftover flag from an earlier test would otherwise make it pass for the wrong reason.

@meta-cla meta-cla Bot added the CLA Signed label Sep 22, 2026
@github-actions github-actions Bot added changelog: fix Took care of something that wasn't working. type: bug The issue is a confirmed bug. labels Sep 22, 2026
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

📦 Latest Plugin Build

Built at: 2026-11-06T11:45:10Z
Commit: a4cf04d
Size: 1.9M

Download: Click here to download the plugin

To download: Click the link above → Scroll to bottom → Download "facebook-for-woocommerce" artifact

WordPress renders its 404 template for any URL it cannot resolve, and the
default rewrite rules hand it requests for missing files as well as mistyped
URLs. Every one of those responses fired a PageView: the CAPI event, the
client-side fbq track, and the noscript image that requests ev=PageView.

None of them is a visit to the store. They inflate PageView and attribute
traffic to URLs that do not exist — most visibly a missing JavaScript file
producing page views of itself.

The base pixel code still prints on a 404, so window.fbq stays defined for
anything else on the page; it only initializes the pixel and reports nothing
on its own. Stores that deliberately track 404s can restore the old behaviour
with the wc_facebook_should_report_page_view filter.
@vahidkay-meta
vahidkay-meta force-pushed the fix/no-pageview-on-404 branch from 9b8edcc to b6513a9 Compare November 5, 2026 10:25
The test site uses plain permalinks, so go_to( '/no-such-url-x/' ) loaded
the home page and the 404 tests failed their precondition. Request a post
ID that cannot exist instead, which is a 404 under any permalink setting.

go_to() also left $_SERVER['REQUEST_URI'] pointing at the fake URL. The
crash guard tests that run later read it as the crashing request's path,
probed it and then /, and saw two self-checks where they expect one.
Restore $_GET and REQUEST_URI after each test.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: fix Took care of something that wasn't working. CLA Signed type: bug The issue is a confirmed bug.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant