<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: foxclerec</title>
    <description>The latest articles on DEV Community by foxclerec (@foxclerec).</description>
    <link>https://dev.to/foxclerec</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F773588%2F8403005e-e750-4d66-b0ec-9cb0bc46d609.png</url>
      <title>DEV Community: foxclerec</title>
      <link>https://dev.to/foxclerec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foxclerec"/>
    <language>en</language>
    <item>
      <title>[FREE] A self-hosted WordPress analytics plugin where your visitor data never leaves your server</title>
      <dc:creator>foxclerec</dc:creator>
      <pubDate>Mon, 15 Jun 2026 04:20:39 +0000</pubDate>
      <link>https://dev.to/foxclerec/free-a-self-hosted-wordpress-analytics-plugin-where-your-visitor-data-never-leaves-your-server-4o4a</link>
      <guid>https://dev.to/foxclerec/free-a-self-hosted-wordpress-analytics-plugin-where-your-visitor-data-never-leaves-your-server-4o4a</guid>
      <description>&lt;p&gt;I recently released a free, privacy analytics plugin for WordPress. It's cookieless, stores everything in your own database, and loads zero external resources, so it's GDPR/CCPA friendly without a consent banner.&lt;/p&gt;

&lt;p&gt;After sharing it around, the same handful of questions kept coming up. Instead of answering them one at a time, here they are in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in it
&lt;/h2&gt;

&lt;p&gt;Everything is included for free, no upsells or feature gates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time visitor counter&lt;/li&gt;
&lt;li&gt;Pageviews, unique visitors, bounce rate, average session duration&lt;/li&gt;
&lt;li&gt;Interactive world map with zoom, pan, and country/city drill-down&lt;/li&gt;
&lt;li&gt;UTM campaign tracking with automatic URL cleanup&lt;/li&gt;
&lt;li&gt;Event tracking — outbound links, downloads, mailto/tel clicks, 404s&lt;/li&gt;
&lt;li&gt;Custom events via data attributes or a JS API&lt;/li&gt;
&lt;li&gt;Smart insights — exit pages, dead pages, user journeys&lt;/li&gt;
&lt;li&gt;24-hour peak activity chart and new vs returning breakdown&lt;/li&gt;
&lt;li&gt;Device, browser, and OS detection (server-side)&lt;/li&gt;
&lt;li&gt;Weekly or monthly email reports&lt;/li&gt;
&lt;li&gt;CSV export on every dashboard tab&lt;/li&gt;
&lt;li&gt;Date range selector with custom ranges&lt;/li&gt;
&lt;li&gt;Role-based dashboard access control&lt;/li&gt;
&lt;li&gt;Configurable data retention, IP exclusion, and bot filtering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How can it track visitors without cookies?
&lt;/h2&gt;

&lt;p&gt;Instead of storing an identifier on the visitor's device, it builds an anonymous fingerprint server-side: a one-way SHA-256 hash of the IP plus a few request signals (User-Agent, screen size, language, timezone).&lt;/p&gt;

&lt;p&gt;The raw IP is never stored, only the hash. The salt rotates daily (it includes the UTC date), so the same visitor produces a &lt;em&gt;different&lt;/em&gt; hash every 24h, and yesterday's data can't be linked to today's. That's enough to count unique visitors and sessions within a day without ever setting a cookie or touching localStorage. It's the same audience-measurement approach the well-known privacy analytics tools use, and it meets the "limited lifespan" criterion for consent-exempt tracking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it work with full-page caching?
&lt;/h2&gt;

&lt;p&gt;Yes. The tracking is a small client-side script that fires on page load and POSTs to &lt;code&gt;admin-ajax.php&lt;/code&gt;. That endpoint is dynamic and never cached by page-cache plugins or CDNs.&lt;/p&gt;

&lt;p&gt;The cached HTML just contains the static &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag. The actual hit is recorded when the browser calls the uncached endpoint. The script also ships with flags to survive Rocket Loader, Autoptimize, and WP Rocket optimizations.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is it different from Google Analytics?
&lt;/h2&gt;

&lt;p&gt;The big one: nothing leaves your server. All data stays in your own WordPress database, with no Google, no third-party servers, no data sharing. That also means no cookie banner, and no sampling, so you see 100% of your traffic instead of estimates.&lt;/p&gt;

&lt;p&gt;It's also much lighter than GA's tag, so no measurable slowdown on your pages. And it lives right inside WP Admin: install, activate, done. No account, no tags, no property setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't ad blockers block it?
&lt;/h2&gt;

&lt;p&gt;Far less than third-party tools, though I won't claim it's 100% unblockable.&lt;/p&gt;

&lt;p&gt;The difference is that the script is served from your own domain, not from a known third-party tracker domain, so there's no external host for blocklists to match. The request also goes to &lt;code&gt;admin-ajax.php&lt;/code&gt;, a normal WordPress endpoint that blockers leave alone, since blocking it would break countless sites. Compared to anything loading from a separate tracking domain, it's a lot more resilient in practice.&lt;/p&gt;




&lt;p&gt;That's most of what people asked. If you've got more questions, drop them in the comments and I'll add them here.&lt;/p&gt;

&lt;p&gt;It's free and on the WordPress.org directory if you want to try it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wordpress.org/plugins/zenmarkup-privacy-analytics/" rel="noopener noreferrer"&gt;ZenMarkup Privacy Analytics&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>analytics</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
