Easy Server Side Tracking

Changelog

5.2.6

  • Fix: events failed to send on sites where a theme/plugin defines a global function fetch(){…} (e.g. the common admin-ajax “data_fetch” live-search snippet), which overwrites the browser’s native window.fetch. The tracker now detects a shadowed fetch and recovers a pristine native fetch (via a hidden same-origin iframe) so events send normally. Init marker advanced to “v5”.

5.2.5

  • Fix: prevent an uncaught JavaScript error (“Cannot read properties of undefined (reading ‘then’)”) when a content blocker, privacy extension or browser tracking-protection neutralises window.fetch for the collector domain. The tracker now detects that the request was blocked and drops the event gracefully instead of throwing. Init marker advanced to “v4”.

5.2.4

  • Maintenance: rebuild the public tracker bundle so aggressive JS optimizers/CDNs (e.g. WP Rocket’s content-hashed cache) generate a fresh file and stop serving an older cached copy. The initialization marker was advanced to “v3” so the loaded build is verifiable in the browser console. No functional code changes.

5.2.3

  • Maintenance: version bump to change the tracker script’s cache-busting query string, forcing browsers and CDNs to reload the corrected public bundle from 5.2.2. No functional changes to the plugin.

5.2.2

  • Fix: resolve a JavaScript error (“Cannot read properties of undefined (reading ‘then’)”) when sending events; rebuild the public tracker bundle so the corrected code is served.

5.2.1

  • COMPLIANCE: Neutralised the worker quota notice. When the managed service pauses a site (after it reaches its plan’s monthly event volume), the admin notice now states the service paused tracking and links to the dashboard — the “monthly limit reached / Upgrade your plan” wording and the pricing link were removed. The plugin itself locks no features; all tracking is free and fully functional, and the volume is enforced by the external service, not the plugin.
  • DOCS: Added setup/connection and plan-change FAQ entries to the readme.

5.2.0

  • COMPLIANCE (WordPress.org Guideline 5 — Trialware): Removed the entire client-side license subsystem. Deleted the license manager and tamper-detection guard, removed the in-WordPress license-key field, and removed all local tracking and caching of event counts and plan limits. The plugin is free and fully functional with no license key.
  • Plans, usage, limits, and upgrades are now managed entirely on the dashboard (easyserversidetracking.com). Limits are applied and enforced server-side by the managed worker; the plugin only provisions the site and sends events. The admin “License” screen is now a “Connection” screen that links to the dashboard.
  • Cleanup: all obsolete license, event-count, plan-limit, permission, and tamper-hash options are removed on upgrade.

5.1.7

  • COMPLIANCE FIX: Two wp_head outputs (the googletagmanager preconnect hint and the early gtag consent script) were still gated on the provisioning id alone, so they could fire on grandfathered or consent-withdrawn sites. Both now require explicit consent AND provisioning, matching the tracker.
  • HARDENING: The page-token REST endpoint now refuses to mint a worker token without consent (defense-in-depth, mirroring the /g/collect proxy).
  • RELIABILITY: The browser’s collect URL is now normalized to a single /collect path before use, so a stored value without that suffix can’t send events to the wrong endpoint. The token-refresh request no longer builds a double-slash URL.
  • NOISE: The “Not provisioned” frontend message is now debug-gated instead of warning on every event.

5.1.6

  • HOTFIX: The 5.1.4 consent gate replaced the provisioning check on the frontend tracker and the periodic license refresh instead of adding to it. On sites that had a consent record but were not provisioned, the tracker loaded and then dropped every event as “Not provisioned”. Both paths now correctly require BOTH explicit consent AND a provisioning id before loading or phoning home.

5.1.5

  • MAINTENANCE: Internal refactor (no change to behavior). Centralized all outbound service calls behind a single HTTP helper, extracted the consent logic (site-owner opt-in gate + visitor gcs→consent mapping) into a dedicated, unit-tested class, and split the admin notices into their own class.
  • TESTS: Fixed the native unit-test bootstrap (it never defined WPINC, which silently aborted the suite) and added coverage for the consent mapping.

5.1.4

  • PRIVACY/COMPLIANCE: Explicit opt-in consent is now the single gate for ALL connections to the service and ALL tracking. Until the site administrator gives consent, the plugin does not contact the service, does not run the periodic license/usage refresh, does not load any tracking script, and rejects the /g/collect proxy. The mere presence of a provisioning id (esst_site_id, which can survive an upgrade) no longer enables anything. Legacy installs with a provisioning id but no consent record now stay OFF and show a notice prompting the admin to review and enable. Withdrawing consent fully stops tracking.
  • PRIVACY: Server-side event logs forwarded to the worker now carry the visitor’s real GA4 consent state (derived from the gtag gcs signal, defaulting to denied) instead of a hardcoded “granted” value.
  • SECURITY: $_GET WooCommerce variation attributes are now unslashed, sanitized (sanitize_key / sanitize_text_field) and validated before being passed to WooCommerce’s variation matcher.

5.1.3

  • HOTFIX: Resolves a fatal Class “JachtSST\Admin\GA4_Server_Side_Tagging_Admin” not found on the License page in 5.1.2 — the consent panel referenced the pre-rename class symbol. Fixed to use the real class name Jachtsst_Server_Side_Tagging_Admin.

5.1.2

  • PRIVACY/UX: The License page now shows a persistent “Data sharing consent” panel above Re-provision. It lists exactly what is sent and where, with a checkbox that records explicit consent (timestamp + user + the exact disclosure text shown). Grandfathered installs (provisioned by an older version) see this with an unticked box; ticking it records consent retroactively and unlocks the Re-provision button. The Re-provision AJAX now refuses to phone home without a stored or in-request consent record.
  • COMPLIANCE: Text domain in source code now matches the actual plugin slug jacht-easy-server-side-tracking (previously had a stale reference to the slug originally proposed in the wp.org review).
  • COMPLIANCE: Restored phpcs:ignore comments on the three settings-handler POST reads so Plugin Check no longer reports false-positive sanitization warnings; the sanitizer callbacks do handle JSON-decode and per-field cleanup.
  • DOCS: Tested up to: 7.0.

5.1.1

  • FIX: Page/event tokens now sign with the hashed signing key, matching the ingestion endpoint. Resolves bad_page_token / HMAC verification failures so events are accepted without re-provisioning.

5.1.0

  • Provisioning is now an explicit opt-in; no data is sent until you connect.
  • Logs are stored in the uploads directory instead of the plugin folder.
  • Stricter input sanitization and unique internal prefixes for WordPress.org compliance.

5.0.4

  • FIX: Tracker init no longer throws TypeError: setupEventCountFlushHandlers is not a function. The orphaned calls (left over from the v5.0.2 client-side limit-enforcement removal) have been deleted, so the tracker reaches the end of its init path again.
  • UI: License page no longer exposes the management endpoint URL or the ESST_MGMT_BASE_URL override note. Customers shouldn’t be altering this endpoint.
  • Cache-bust: the version bump forces fresh JS to be loaded after the v5.0.3 release that introduced the broken init path.

5.0.3

  • SECURITY: Added CSRF nonce verification to the encryption-key regeneration AJAX endpoint.
  • PRIVACY: Removed the client-side fallback chain to ipapi.co, ipinfo.io, and json.geoiplookup.io. Geo-resolution is performed server-side by the managed worker from the request IP. No visitor IP is sent to third parties by the plugin.
  • COMPLIANCE: Renamed the unprefixed event_count option to ga4_event_count (with an automatic one-time migration). Sanitized all $_SERVER reads with sanitize_text_field( wp_unslash() ). Removed shipped legacy plugin-v4/ source tree and the wp-admin/includes/upgrade.php test mock.
  • README: Added External services section documenting every external endpoint the plugin contacts, with terms and privacy links. Tags revised to remove trademarked terms.

5.0.2

  • REMOVE: Client-side event-limit enforcement. The admin Settings page no longer hides itself when a cached “limit reached” flag is set. Quota is enforced exclusively server-side — the worker returns 429 quota_exceeded, the management server returns allowed: false in report-usage.
  • FIX: License page shows the paid-plan name and limit immediately after activation — the management server now propagates plan_id onto lm_websites on license/activate and report-usage.

5.0.1

  • FIX: All events now use a single canonical payload format with top-level client_id, session_id, user_id, consent, and context — previously some paths (scroll, click, batched events) sent client_id nested under params which the central worker rejected with HTTP 400 missing_client_id.
  • FIX: Worker bad_page_token (401) responses now trigger a token refresh + retry once, so tabs left open across a re-provision auto-heal.
  • FIX: Re-provisioning rotates the secret in place on the central worker instead of creating a new cf_site_id every time — no more orphaned worker sites and no more HMAC mismatches.
  • FIX: Gtag /g/collect proxy on the WP site also fires a server-side log_only POST to the central worker so events are counted even when content blockers block the JS bundle on the customer’s browser.
  • FIX: License page correctly shows “Unlimited” for paid unlimited plans (was showing the free-tier 10,000 cap).
  • REFACTOR: Removed legacy sendAjaxPayload and sendBatchPayload — esstSendEvent is the single event-sending path. Worker no longer receives batches; each event is one request.
  • REFACTOR: Removed all remaining customer-hosted Cloudflare Worker references from the Settings UI.

5.0.0

  • MAJOR: Plugin no longer requires a customer-hosted Cloudflare Worker.
  • MAJOR: Events post directly to the managed collect endpoint (collect.easyserversidetracking.com) using a short-lived per-page HMAC token.
  • MAJOR: Removed Event Monitor / Event Processor / Tracking Logs admin pages. All event analytics now live on the management dashboard.
  • NEW: Auto-provisioning on activation — no license key required for the free tier.
  • NEW: Status admin page shows site_id, plan, this-month usage. (Merged into the License page in a later release.)
  • REMOVED: ga4_event_queue / ga4_event_logs tables (data not migrated).
  • REMOVED: Custom transmission method setting, CF Worker URL setting, JWT encryption setting, test mode toggle, “disable all IP” setting.
  • The client-side session management setting is now always enabled.

3.7.x

Earlier 3.7.x releases focused on plugin-check compliance and security hardening. See the GitHub release notes for details. The plugin’s data flow and admin surface were rewritten in 5.0.0; users on 3.7.x should re-test after upgrading.

Plugin Website
Visit website

Version:
5.2.6
Last Updated
July 1, 2026
Requires
WordPress 5.2
Tested Up To
WordPress 7.0
Requires PHP
7.2

Share Post

Join our newsletter.

Get insights into what’s happening at ChangelogWP right in your inbox. We don’t believe in spam.