Skip to content

Outbound link tracking broken with REST + sendBeacon #174

@parhumm

Description

@parhumm

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

  1. Install WP SlimStat with default settings (REST transport, javascript_mode=off)
  2. Visit any page - pageview tracked correctly
  3. Click an external link (e.g., https://www.google.com)
  4. Check access log - outbound_resource is 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions