Pixel Made Simple

Description

Pixel Made Simple is a deliberately minimal tracking plugin. No jQuery, no frameworks, no DOM listeners in the frontend – just the official platform loaders (loaded asynchronously) plus a few lines of inline code.

What the plugin does

  • Meta Pixel + Conversions API (CAPI): Browser pixel and server-side events from the same WordPress request. Every event gets one UUID that is passed to both fbq() (eventID) and the Conversions API (event_id), so Meta deduplicates the pair automatically.
  • Fire-and-forget CAPI: Server-side events are sent non-blocking via wp_remote_post() – no impact on page load time. user_data contains client IP, user agent, the _fbp/_fbc cookies (with a fallback from fbclid) and – optionally – the SHA-256 hashed email address of logged-in users.
  • Google Ads (gtag.js): Conversion tracking with your Google Tag, including Google Consent Mode v2 defaults – ad_storage, ad_user_data, ad_personalization and analytics_storage start out as “denied” and your banner sends the update. Form leads additionally carry Enhanced Conversions data, hashed to Google’s own rules (they differ from Meta’s, so both values are carried separately).
  • Google Analytics 4: Reuses the same gtag.js loader – enter the Measurement ID and page views and events are picked up. Independent of Google Ads above.
  • TikTok Pixel: The official web events, fired with the same event ID as the matching Meta event.
  • URL-based events: Define any number of URL rules (“exact path” or “URL contains”) that fire a standard or custom event on Meta, Google Ads and TikTok at once, e.g. Lead on /thank-you/. Ideal for thank-you and confirmation pages.
  • Handover to the confirmation page: A confirmation page does not know the email address, so on its own it can only pass on IP and user agent – and Meta barely uses such a server event for attribution. With form lead tracking enabled, the submission hands its event ID and its hashed contact data to the next page through the browser’s sessionStorage. A matching URL rule there reports the same event instead of a second one: if the submission got through, Meta deduplicates the pair; if it was lost during the redirect, the confirmation page is its full replacement. Either way one conversion – with email and phone in the match. With Google Ads configured, the same conversion also carries Enhanced Conversions data (gtag('set','user_data', …)), hashed to Google’s own rules – they differ from Meta’s, so both values are carried separately.
  • Automatic form lead tracking (off by default): Detects submissions of Contact Form 7, Elementor Pro, Fluent Forms, WPForms, Gravity Forms, SureForms and plain HTML forms and fires Lead or Contact in the browser and via CAPI with the same event ID. Email and phone number are hashed with SHA-256 before they leave your server; raw values are never stored or logged. Optional URL filter and automatic exclusion of search, comment and login forms. Submissions that redirect to a confirmation page hand their data over to it (see above).
  • GDPR cookie banner detection (on by default): Recognises Must Have Plugins Cookie Bar, Borlabs Cookie, Complianz, Real Cookie Banner, CookieYes, Cookiebot, SureCookies and any banner that implements the WP Consent API, and holds back browser and server events until the visitor grants marketing consent. Tracking starts right after the click on “Accept” – no reload. Sites without a cookie banner are never blocked. A consent mode lets you choose whether server-side events wait for the banner as well (recommended) or only the browser pixel does.
  • Cookieless analytics (Plausible, Umami, Rybbit): Load the base script of a privacy-friendly analytics provider straight from the Privacy Trackers tab – two fields per provider, the script URL from your dashboard and the site identifier. Deliberately limited to the base script: no custom events, no goals, no server-side connection. Each provider has its own Load without consent switch (off by default); when it is off the tracker waits for consent exactly like the advertising pixels, and when it is on it loads immediately – for that one provider only, while Meta, Google and TikTok stay blocked. Nothing at all is written to your page source until a provider is switched on and both of its fields are filled.
  • Event log: A small table in your WordPress admin lists the most recent browser and server-side events (event name, event ID, platform, status, match keys) so you can verify your setup without leaving WordPress. Filter by status, event name or platform; entries are deleted automatically after 3, 7, 14 or 30 days, whichever you choose.
  • Live debug bar for administrators: A discreet bar at the bottom of the frontend shows consent status (including the detected banner), fired events, event IDs, the CAPI response and the match keys used. Rendered exclusively for logged-in administrators – regular visitors get zero additional bytes.
  • Test event code with auto-expiry: The Meta test event code is removed automatically after 12 hours, so no test traffic ends up in your live reports by accident.
  • Privacy by default: Form lead tracking is disabled on new installations, the CAPI access token is only ever used server-side and never rendered in the frontend, and the event log stores field names only – never values or hashes.
  • Consent statistics: One card above the event log answers a single question – how much of your tracking is the cookie banner eating? Aggregated daily counters only, for 7 or 30 days, with a daily breakdown and a CSV export.
  • Export & import: Download the whole configuration as JSON and apply it on another site in one step.
  • Translation-ready: English source strings and a POT template are included; German and other locales come from translate.wordpress.org.

Pixel Made Simple Pro

Everything described above is included here, without limits or license checks. Pixel Made Simple Pro is a separate plugin for online shops and campaign attribution. It adds WooCommerce and SureCart tracking (ViewContent, AddToCart, InitiateCheckout and Purchase for all four platforms, with a server-side Purchase fallback and optional advanced matching), the TikTok Events API for server-side purchase events, and first-touch/UTM attribution with automatic form fill. Both plugins use the same option keys, so switching between them keeps your configuration.

External services

This plugin connects to third-party tracking services. Nothing is sent until you enter the respective ID/token and switch the platform on. With cookie banner detection enabled, nothing is sent before the visitor has granted marketing consent either – the one exception is a privacy tracker whose Load without consent switch you have turned on yourself, and that exception applies to that provider alone.

Meta (Facebook) – Meta Pixel and Conversions API

  • The browser loads the official pixel script from https://connect.facebook.net/ and sends events to https://www.facebook.com/tr (including the <noscript> fallback image). This happens on every page view for which tracking is active.
  • The Conversions API request goes from your server to https://graph.facebook.com/ whenever a URL event matches or a tracked form is submitted (for a URL event that takes part in the handover to the confirmation page, the browser asks your server to send it). It contains the event name, time, event ID, page URL, the visitor’s IP address and user agent, the _fbp/_fbc cookie values if present and – only where enabled – SHA-256 hashes of the email address/phone number (form leads, logged-in users) or of billing details (Pro e-commerce tracking).
  • Terms of service: https://www.facebook.com/legal/terms – Privacy policy: https://www.facebook.com/privacy/policy/ – Platform terms: https://developers.facebook.com/terms/

Google – Google Ads and Google Analytics 4

  • The browser loads gtag.js from https://www.googletagmanager.com/ and sends page views, conversions and e-commerce events to Google Ads / Google Analytics. For form leads the conversion additionally carries SHA-256 hashes of the email address and – where an international number is available – the phone number (Enhanced Conversions). For purchases with advanced matching enabled it carries the same two plus hashed first and last name, and city, region, postal code and country in the clear. There is no server-side connection to Google. With Consent Mode v2 enabled, all consent signals default to “denied” until your banner updates them. There is no server-side connection to Google.
  • Terms: https://policies.google.com/terms – Privacy: https://policies.google.com/privacy – Google Analytics terms: https://marketingplatform.google.com/about/analytics/terms/us/

TikTok – TikTok Pixel and Events API (the Events API is part of Pixel Made Simple Pro)

  • The browser loads the pixel from https://analytics.tiktok.com/ and sends web events to TikTok. For purchases the server additionally sends an Events API request to https://business-api.tiktok.com/ containing the event, event ID, IP address, user agent, order values and – only where enabled – the hashed email address and, where an international number is available, the hashed phone number.
  • Terms: https://www.tiktok.com/legal/page/global/terms-of-service/en – Privacy: https://www.tiktok.com/legal/page/row/privacy-policy/en – Business products terms: https://ads.tiktok.com/i18n/official/policy/business-products-terms

Plausible, Umami and Rybbit – cookieless analytics (all off by default)

  • Unlike the platforms above, the address contacted here is not part of the plugin. You paste the script URL from your own dashboard into the Privacy Trackers tab; the plugin ships no default and never assembles one from a host name. Which server receives the data therefore depends on your account – the provider’s cloud for a hosted plan, your own machine for a self-hosted instance. The example addresses shown in the empty fields are placeholders, never sent.
  • Nothing is loaded for a provider until you switch it on and fill in both of its fields. Until then not a single line for it appears in your page source.
  • Plausible: the browser loads the script from the address you entered (typically https://plausible.io/js/script.js) and reports a page view for every page on which tracking is active, tagged with the domain you entered. Service: https://plausible.io/ – Terms: https://plausible.io/terms – Privacy: https://plausible.io/privacy – What Plausible collects: https://plausible.io/data-policy
  • Umami: same, from the address you entered (typically https://cloud.umami.is/script.js), tagged with the website ID you entered. Service: https://umami.is/ – Terms: https://umami.is/terms – Privacy: https://umami.is/privacy
  • Rybbit: same, from the address you entered (typically https://app.rybbit.io/api/script.js), with the site ID appended to the URL as ?siteId=. Service: https://www.rybbit.io/ – Terms: https://www.rybbit.io/terms-and-conditions – Privacy: https://www.rybbit.io/privacy
  • The plugin loads each provider’s base script and nothing else: no custom events, no goals, no e-commerce data, and no server-side connection of any kind. What that script then collects is the provider’s business and is described in their own documentation above.
  • Consent: by default each provider waits for marketing consent exactly like the advertising pixels, and starts without a page reload once the visitor accepts. The per-provider Load without consent switch changes that for that one provider only – Meta, Google and TikTok stay blocked either way.

SureCart – licensing and automatic updates (Pro only)

  • The Pro version activates its license and checks for updates against https://api.surecart.com. This happens when you activate or deactivate a license on the “License” page, and when WordPress checks for plugin updates (the result is cached for three hours). Transmitted are the license key you entered, your site URL and your site title.
  • The free version never contacts this service. It is updated through WordPress.org and contains no update checker of its own.
  • Terms: https://surecart.com/terms-and-conditions/ – Privacy: https://surecart.com/privacy-policy/

A freshly activated Pixel Made Simple contacts nothing at all: with no platform configured, the plugin writes no third-party script, image or request into your pages. Every connection described above needs a setting you made yourself. The settings pages link to https://pixelmadesimple.com (documentation, tutorials, Pro upgrade). These are plain links – no data is transmitted unless you click them. The free version contains no update checker or telemetry of its own; updates come from WordPress.org.

Privacy

  • Personal data is only ever sent to the platforms above, never stored by the plugin. Email addresses and phone numbers from form submissions are hashed (SHA-256) in memory and discarded.
  • The event log stores event names, event IDs, status codes and the names of the match keys used (e.g. em, fbc) – never the values.
  • The consent statistics store aggregated daily counters only: one row per calendar day with three integers (sent, blocked by consent, not configured). There is no IP address, no user agent, no event ID and no timestamp below day level – the plugin does not and cannot track who declined consent. Rows older than 30 days are deleted automatically.
  • The handover to the confirmation page uses the browser’s sessionStorage and holds an event ID plus SHA-256 hashes – four of them since 0.11.1 (Meta and Google normalise differently), never a plain-text email address or phone number. The entry is never sent to the server, does not survive closing the tab, expires after 10 minutes and can be used exactly once. In the default consent mode it is not created at all without marketing consent.
  • The first-touch attribution cookie pxms_attribution (Pro, off by default) stores UTM parameters and click IDs for 30 days in a first-party cookie.
  • Please check with your data protection officer whether the “Block browser pixels only” consent mode is permissible for your site; the default (“Fully GDPR compliant”) blocks server-side events as well.

Screenshots

Installation

  1. Upload the plugin via Plugins Add New Upload Plugin and activate it, or install it from the WordPress.org plugin directory.
  2. Open Pixel Made Simple in the admin menu, expand Meta (Facebook), enter your Pixel ID and switch the platform on.
  3. Optional: paste your Conversions API access token (Meta Events Manager Data sources Settings Conversions API) – the Conversions API switches on automatically.
  4. In the URL Events tab, add rules for your thank-you or confirmation pages. For forms without a redirect, enable Automatic form lead tracking in the Advanced Tracking tab instead.
  5. Check the Event Log and the live debug bar (visible to administrators in the frontend) to verify that events arrive.

FAQ

Which services does the plugin contact?

Only the ones you configure yourself. With no platform set up it writes no third-party script, image or request into your pages at all. Every address it can contact, what is transmitted and when, is listed under External services below.

How do I test the Meta server events?

Enter the test event code from the Events Manager (tab Test events) in the General tab. Server events then show up there in real time. The code is removed automatically after 12 hours. For debugging you can make the request blocking, after which the raw Meta response is written to the debug log when WP_DEBUG_LOG is enabled:

add_filter( 'pxms_capi_blocking', '__return_true' );

Do the privacy trackers need a cookie banner consent?

That is your decision, and the plugin lets you make it per provider. By default every privacy tracker runs through exactly the same marketing consent gate as the Meta, Google and TikTok pixels – nothing loads until the visitor accepts, and it then starts without a page reload. The Load without consent switch changes that for one provider only; the advertising platforms are never affected by it.

The background: Section 25 TDDDG covers storing information on, or reading it from, a visitor’s device. A tracker that sets no cookie and uses no local storage is not covered by it; the GDPR level applies regardless. Whether that reasoning holds depends on the specific service and where it is hosted, and it is legally contested. Pixel Made Simple makes no claim about any third-party service being compliant – it only provides the setting.

Which script URL do I enter for Plausible, Umami or Rybbit?

The one from your own dashboard, copied verbatim – for example https://plausible.io/js/script.js, https://cloud.umami.is/script.js or https://app.rybbit.io/api/script.js. Self-hosted instances use your own domain instead.

The plugin deliberately does not assemble that address from a host name. All three providers have changed their paths at least once (Umami moved from /umami.js to /script.js, Plausible issues newer accounts a per-site tracker filename, Rybbit switched from an attribute to a query parameter). A path guessed by the plugin would eventually be silently wrong: the script loads and no data arrives.

Do the privacy trackers show up in the event log or the consent statistics?

No, and that is intentional. They are not conversions, they never go through the Conversions API, and counting them would dilute exactly the numbers you use to investigate missing advertising conversions. The event log and the consent statistics keep reporting on Meta, Google and TikTok only.

How does the plugin work with my cookie banner?

The automatic cookie banner detection (on by default) checks the consent cookies of the supported banner plugins and the WP Consent API on the server. Without marketing consent the browser scripts are deferred (they listen for the banner’s consent events and start right after the click on “Accept”) and the Conversions API request is not sent. If no supported banner is installed, nothing is blocked.

For unsupported banners you can provide the consent result yourself:

add_filter( 'pxms_has_marketing_consent', function ( $consent ) { return my_marketing_consent(); } );

And you can suppress all tracking server-side:

add_filter( 'pxms_allow_tracking', function ( $allow ) { return my_consent_check(); } );

Does the plugin work with page caching?

The browser pixel: yes. The Conversions API is normally only triggered when PHP actually renders the page, so with aggressive full-page caching you should exclude your conversion pages from the cache – otherwise CAPI events are not sent at all, and every visitor shares the one event ID baked into the cached HTML.

One exception, since 0.11.0: a URL event that participates in the handover to the confirmation page is sent from the browser and generates its event ID per visitor. That one works on a cached page. All other URL events still need the page to be excluded from the cache.

My thank-you page is on a different domain. Does the handover still work?

No. sessionStorage belongs to exactly one origin, so nothing travels to another domain or subdomain – the same applies to a form inside an iframe from a different origin. In those cases both events are counted separately, exactly as before version 0.11.0. If the confirmation page is on a subdomain, moving it to a path on the main domain (/thank-you/ instead of thanks.example.com) is enough to get the full match.

Google Ads shows no enhanced conversions data. What is missing?

Three things have to line up. In your Google Ads account, Enhanced Conversions must be enabled for that conversion action and the customer data terms accepted – without that Google discards the data silently and still counts the conversion. In the plugin, the event needs a conversion label. And for the phone number Google requires the international format: if your form collects 0151 … without a country code, only the email address is sent. The filter pxms_normalize_phone can add the country code.

Which filters are available?

  • pxms_allow_tracking – allow or suppress tracking globally.
  • pxms_has_marketing_consent – override the result of the cookie banner detection (guards the browser pixel).
  • pxms_has_server_consent – the same for server-side signals (Conversions API, TikTok Events API). Only relevant when the consent mode is set to “Block browser pixels only”.
  • pxms_consent_banner_active – register your own banner with the detection.
  • pxms_consent_events – additional banner events for the frontend listener.
  • pxms_capi_event_data – modify a single CAPI event before it is sent (e.g. add custom_data).
  • pxms_capi_user_data – modify the user_data payload.
  • pxms_normalize_phone – adjust the normalised phone number before hashing (e.g. add a country code). Also decides whether Google gets a phone number at all: without a country code there is no valid E.164 value, and none is sent.
  • pxms_graph_api_version – override the Graph API version.
  • pxms_capi_blocking – send the CAPI request blocking (debugging).
  • pxms_tiktok_capi_blocking – the same for TikTok Events API requests (Pixel Made Simple Pro, debugging).

Upgrading from “Lightweight Meta Pixel & CAPI Tracker”? These filters used to be called lmpct_*. Custom code that hooks into one of them must be updated to the pxms_* names – see the 0.6.0 changelog entry.

How do I translate the plugin?

Source strings are English. The /languages folder contains the POT template and the finished German translation (-de_DE.po/.mo). Custom translations made with Loco Translate are best stored under “System” (wp-content/languages/loco/plugins/) so they survive updates.

Is all data removed on uninstall?

Yes, as soon as neither variant (free or Pro) is installed anymore. uninstall.php then deletes all plugin options including the stored access token, the event log table and the scheduled cleanup task. Switching from free to Pro (or back) keeps your configuration – both use the same option keys.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Pixel Made Simple” is open source software. The following people have contributed to this plugin.

Contributors

Translate “Pixel Made Simple” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

The complete changelog for every release is at https://pixelmadesimple.com/changelog/ – this file lists the most recent ones.

0.12.7

Hardening. No change to tracking, settings or anything you can see.

  • Changed: five values have to reach the plugin byte for byte – cookie contents written by consent banners (JSON, Base64, percent-encoded), the request path, and the email address before it is hashed. A standard sanitiser would quietly destroy them: it strips every %XX sequence, which is how a percent-encoded path or a banner cookie turns into something that no longer matches. Those five now pass through one filter that removes control characters and nothing else – the character class behind log injection and truncated strings, and the one class that appears in none of those formats.

0.12.6

Code hygiene. No change to tracking, settings or anything you can see.

  • Changed: the two form endpoints sanitise their input in the order a static analyser can follow. The sanitising itself is unchanged and was never missing – it was written in a way that made the WordPress Plugin Check report eight false alarms, in the one file where a false alarm costs the most attention.
  • Changed: three deliberate exceptions now say so at the line itself: the two queries against Borlabs’ own tables, and the version-less loading of third-party scripts – appending a version number to someone else’s URL has no purpose.
  • Added: the length limits on both public endpoints are now covered by tests. They had never been, and they are exactly what this release moved.

0.12.5

One upgrade notice on the e-commerce tab instead of two. Nothing else changes.

  • Changed: the info box above the WooCommerce section said the same thing as the box directly below it, down to a second “Learn more” button. It only ever appeared when a shop plugin was detected – which is exactly when that box appears too, so it never added anything. The WooCommerce and SureCart boxes carry that information themselves.

0.12.4

The free version no longer contains a licence check anywhere. Where it previously asked “is this the paid version?” it now asks “is this code present?” – which is what actually differs between the two packages. Nothing changes for you; the switches you can see and use are the same ones as before.

  • Changed: every remaining gate in the admin interface asks whether the class implementing the feature exists, not whether a licence is active. In the free package the implementation is simply absent, so its controls are absent too – rather than present and refusing to work.
  • Changed: the endpoint behind the instant-save toggles now names, per setting, the class that has to be there for the value to mean anything. A toggle that could not take effect no longer stores a value.
  • Fixed: the icon on the “Upgrade to Pro” buttons was invisible. It had kept the cream colour from back when those buttons were blue; on the white button it has been there all along, just unreadable.

0.12.3

Google Ads, Google Analytics 4 and the TikTok Pixel are now part of this plugin, and every remaining limit is gone – no cap on URL events, no shortened event log, no locked filters or exports. Nothing this plugin ships is restricted any more, which is what the WordPress.org plugin directory guidelines require.

  • Changed: Google Ads (gtag.js incl. Consent Mode v2), Google Analytics 4 and the TikTok Pixel are available here. A configuration made under Pro is picked up unchanged – both variants have always used the same option keys.
  • Changed: URL events are no longer capped at two.
  • Changed: the event log keeps 3, 7, 14 or 30 days, whichever you choose, and its status, event and platform filters work.
  • Changed: the consent statistics offer the 30-day period, the daily breakdown and the CSV export.
  • Changed: JSON export and import of the whole configuration are available.
  • Changed: form leads can be sent to TikTok and Google Ads, including Enhanced Conversions for the Google conversion.
  • Changed: Pixel Made Simple Pro now covers what only it can provide – WooCommerce and SureCart e-commerce tracking, the TikTok Events API for server-side purchase events, purchase advanced matching, and first-touch/UTM attribution with automatic form fill. No existing Pro installation loses a feature.
  • Changed: the two remaining references to Pro in the admin are plain informational boxes. No padlock icons, no greyed-out controls and no upgrade prompts anywhere else.
  • Changed: the TikTok Events API fields (toggle, access token, test event code) are only rendered when the class implementing them is present. They drive the e-commerce purchase path and would otherwise have been controls without an effect.
  • Changed: the plugin description no longer compares this plugin to others.
  • Removed: the FREE_EVENT_LIMIT constant and free_event_limit_reached(), and resolve_event_platforms(), which enforced the per-event Google/TikTok lock server-side.
  • Removed: the $is_pro argument of resolve_summary_days(); the constant FREE_SUMMARY_DAYS is now DEFAULT_SUMMARY_DAYS and FREE_LOG_RETENTION_DAYS is gone.
  • Removed (free package only): load_plugin_textdomain(). WordPress has loaded translations for plugins hosted on WordPress.org by itself since version 4.6. Pixel Made Simple Pro is not distributed through the directory and keeps the call.
  • Removed (free package only): the compiled German translation (.po/.mo) is no longer shipped. Translations now come from translate.wordpress.org and land in wp-content/languages/; the .pot template stays in the plugin.
  • Changed: gtag.js and the three privacy tracker scripts are registered through wp_enqueue_script() instead of being written into the page directly. Plausible’s data-domain and Umami’s data-website-id are attached through the script_loader_tag filter; Rybbit carries its ID in the query string as before. Nothing changes for the consent gate: without consent the loader still lives as a plain string inside the consent bootstrap and no src attribute reaches the markup.
  • Changed: the debug bar’s CSS moved from an inline <style> block into a registered stylesheet (wp_add_inline_style()). It had to move from the footer to wp_enqueue_scripts to be printed at all.
  • Changed: superglobals are sanitised where they are read, not a line later. Five values are documented exceptions: they are only ever compared or hashed, never printed, and any sanitiser would silently change them into something else. The three private helpers in the form endpoints now receive their raw values as parameters instead of reading $_POST themselves, so the obligation to verify the nonce first is visible at the call site.
  • Changed: the configuration import reads the uploaded file through WP_Filesystem, falling back to file_get_contents() on installations without direct filesystem access so the import keeps working there.
  • Changed: every table and column name in a database query goes through the %i placeholder of $wpdb->prepare() instead of string interpolation. This includes the two queries that read Borlabs Cookie’s own tables.
  • Breaking: minimum WordPress version raised from 5.8 to 6.3. Sites below 6.3 will not be offered this update. That is what makes the loading strategy (async/defer) available to enqueued scripts through the official API instead of a filter of our own.
  • Breaking: every prefix changed from pms to pxms. The directory guidelines require at least four characters, and pms has three. This affects class names, constants, option keys, both database tables, the cron hook, the attribution cookie, order meta keys, AJAX actions, script handles, the JavaScript globals, the CSS classes and the admin page slug – a bookmark to the old settings URL will no longer resolve.
  • Breaking: the twelve public filters were renamedpms_capi_blocking is now pxms_capi_blocking, and so on for all of them. There is no compatibility layer. If you hook into one of them from a snippet or a child theme, update the name; in particular pxms_normalize_phone, which decides whether Google receives a phone number at all.
  • Breaking: settings are not migrated. The option keys and both tables changed name, so the plugin starts with its defaults after this update and the old rows stay behind unused. This was a deliberate decision – at the time of the rename the plugin ran on two test sites, and carrying migration code for them would have meant carrying it forever.
  • Changed: neither package deactivates the other any more – a plugin must not do that. The free version checks whether a Pro package is active, and whether its file is actually still there, and then does not load at all: no hook, no menu, no tracking. It stays in the plugin list and says so; deactivate it whenever you like. Should Pro be deactivated later, the free version takes over again on the next request.

0.12.2

Corrects the plugin header. No change to tracking behaviour, no new setting.

  • Fixed: Plugin URI and Author URI carried the same address in 0.12.1. They have to differ – the plugin URI describes this plugin, the author URI describes the person who wrote it. Author and Author URI name the author again, as they did before 0.12.1.

0.12.1

Prepares the free version for the WordPress.org plugin directory. No change to tracking behaviour, no new setting.

  • New: The plugin has its own menu icon in the WordPress admin instead of the generic chart symbol. Like the built-in icons it follows your admin colour scheme and highlights while you are on one of its pages.
  • Changed: the External services section of this readme now documents Plausible, Umami and Rybbit as well – which service is contacted, when data flows, and links to each provider’s terms and privacy policy. As before, the address contacted is the one you enter yourself; the plugin ships no default and never builds one.
  • Changed: the changelog shown in the plugin directory lists the most recent releases only. WordPress.org truncates a longer one mid-sentence, so the full history now lives at https://pixelmadesimple.com/changelog/.
  • Changed: the recent changelog entries are now in English. Older ones stay as they were written – an entry records what changed at the time and is not rewritten afterwards.
  • Added: the complete GPL-2.0 licence text now ships with the plugin.

0.12.0

New Privacy Trackers tab: Plausible, Umami and Rybbit can now be embedded directly – cookieless analytics alongside the advertising pixels. Available in the free version too.

  • New: Embed Plausible, Umami and Rybbit. Two fields per provider – the script URL from your dashboard and the site identifier. That loads the base script, nothing more. The providers carry their identifier differently (Plausible data-domain, Umami data-website-id, Rybbit as a parameter on the URL); the plugin builds the snippet each one actually expects.
  • Why the full script URL instead of just the domain: an address the plugin assembled from a host name could go silently wrong the moment a provider changed its path or handed out a different filename. That is not hypothetical – Umami renamed its tracker from /umami.js to /script.js in version 2, one of that release’s documented breaking changes. And such a failure looks like success: the script loads, and nothing arrives. So copy the address verbatim from your dashboard; the plugin ships no default and never builds one.
  • New: A Load without consent switch – per provider, off by default. Off means: the tracker waits for consent just like the Meta, Google and TikTok pixels, and starts after the click on “Accept” without a reload. On means: it loads immediately – and only it. The advertising platforms are untouched either way.
  • On how to read that switch: Section 25 TDDDG covers storing information on, or reading it from, a visitor’s device. A tracker that sets no cookie and uses no local storage is not covered by it; the GDPR level is unaffected. Whether that reasoning holds depends on the specific service and where it is hosted, and it is legally contested. The plugin makes no claim about whether a third-party service is compliant – it only provides the setting.
  • Deliberately kept small: the base script only. No custom events, no goals, no server-side connection, no e-commerce mapping. That is a decision, not an unfinished state.
  • As long as a provider’s switch is off or one of its two fields is empty, not a single line for it ends up in your page source.
  • The privacy trackers run neither through the Conversions API nor through the event log nor through the consent statistics. They are not conversions, and they should not dilute the numbers you use to chase missing advertising conversions.
  • Changed: a site that uses only a privacy tracker and has no advertising pixel set up at all is now served. Until now nothing would have been output there.