-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Bug: Outbound link tracking broken with REST transport + sendBeacon
Summary
External link (outbound) tracking, download tracking, and exit-time updates are broken when using the default REST API transport. The JavaScript tracker sends interaction data via navigator.sendBeacon() (Content-Type: text/plain), but the REST handler overwrites correctly-parsed tracking data with an empty/incomplete payload.
Root Cause
TrackingRestController::handle_tracking() (line 131-145) calls $request->get_params() and overwrites wp_slimstat::$raw_post_array. WordPress REST API does not parse text/plain request bodies, so get_params() returns empty data for sendBeacon requests — destroying the correct data already parsed from php://input at plugin init (wp-slimstat.php:1559-1575).
Introduced by: commit cfb09a21 (2026-02-21, "fix not collecting data")
Impact
| Request type | JS transport | Works? |
|---|---|---|
| Initial pageview (new) | XHR (useBeacon=false) |
Yes |
| Interaction / outbound link | sendBeacon (useBeacon=true) |
No |
| Download tracking | sendBeacon | No |
| Exit time (dt_out) | sendBeacon | No |
Reproduction
- Install WP SlimStat with default settings (REST transport,
javascript_mode=off) - Visit any page - pageview tracked correctly
- Click an external link (e.g.,
https://www.google.com) - Check access log -
outbound_resourceis empty
Suggested Fix
In handle_tracking(), merge with the already-parsed raw_post_array instead of overwriting:
$payload = $request->get_params();
if (!is_array($payload)) {
$payload = [];
}
// Preserve sendBeacon text/plain data already parsed from php://input
if (!empty(\wp_slimstat::$raw_post_array)) {
$payload = array_merge($payload, \wp_slimstat::$raw_post_array);
}
$payload['action'] = 'slimtrack';
\wp_slimstat::$raw_post_array = $payload;Code References
| File | Lines | Description |
|---|---|---|
src/Controllers/Rest/TrackingRestController.php |
131-145 | Overwrites raw_post_array |
wp-slimstat.php |
1559-1575 | Correct php://input parsing for sendBeacon |
wp-slimstat.js |
381-387, 417 | sendBeacon default for interactions |
src/Tracker/Ajax.php |
289-321 | Server-side outbound link path |
Environment
- WP SlimStat (current main branch)
- Default REST transport
- Any modern browser with sendBeacon support