Turf Stats

Beschrijving

Turf is een selfhosted, cookieless analytics-plugin. Geen Google Analytics, geen Jetpack, geen externe netwerkverzoeken – alles wordt gemeten en opgeslagen in je eigen WordPress-database.

Waarom Turf

  • Cookieless. Deduplicatie van bezoekers gebeurt met een eenrichtingshash van IP + user-agent, nooit met een cookie en nooit met het ruwe IP-adres.
  • Self-hosted. All data lives in your own database; nothing is sent to any
    third party.
  • Geen configuratie nodig. Elk openbaar berichttype en elke taxonomie wordt automatisch bijgehouden, ook types die je later toevoegt.

Wat het volgt

  • Paginaweergaven (gededupliceerd én ruw), unieke bezoekers, weergaven per bezoeker en gemiddelde bezoekduur
  • Apparaat, browser, besturingssysteem, taal en land (via Cloudflare’s header indien beschikbaar – geen GeoIP-opzoekingen)
  • Referrers / traffic sources, UTM campaign parameters, and automatic outbound
    link tracking (full destination URL + the page clicked from)
  • Nieuwe versus terugkerende bezoekers, scrolldiepte en leestijd
  • Zoektermen op de site, inclusief zoekopdrachten zonder resultaat
  • Bezoekersroutes (overgangen van pagina naar pagina), landingspagina’s en een bounce-rate-indicatie – allemaal gereconstrueerd uit sessies
  • Cache-offload: hoeveel verkeer wordt afgehandeld door een pagecache (SiteGround, Cloudflare, …) in plaats van WordPress te belasten
  • 404-hits, reacties per periode, redactionele contentactiviteit, statistieken per auteur
  • Bots & LLM-crawlers (Googlebot, GPTBot, ClaudeBot, …) – server-side bijgehouden en apart gehouden van menselijke bezoekersaantallen
  • WooCommerce.funnel (weergaven, toevoegen aan winkelwagen, afrekenen) en formulierinzendingen (Contact Form 7, Gravity Forms) wanneer die plugins actief zijn

De beheerpagina’s gebruiken native WordPress postboxen: invouwbaar, verplaatsbaar, verbergbaar via Scherminstellingen, en vormgegeven volgens je beheerkleurenschema. De interface is Engels en wordt geleverd met een volledige Nederlandse (nl_NL) vertaling.

Schermafbeeldingen

Installatie

  1. Installeer en activeer de plugin.
  2. Dat is alles – weergaven worden direct geteld voor elk openbaar berichttype en elke taxonomie. Je vindt de rapportages onder het menu “Statistieken” in wp-admin.

Optional extras (a visible view counter, click tracking on specific elements, social-share links, importing historical Jetpack/entry-views view counts via the “Statistics > Import” admin page or WP-CLI) are documented in the plugin’s README on GitHub.

FAQ

Plaatst Turf cookies of is een cookiemelding nodig?

Turf plaatst geen cookies en verstuurt geen data naar externe diensten. Deduplicatie gebeurt met een eenrichtingshash van IP + user-agent; het ruwe IP wordt nooit opgeslagen. De plugin is ontworpen om te passen binnen een grondslag van “gerechtvaardigd belang” voor first-party, geaggregeerde analytics – maar dit is geen juridisch advies: overleg met wie je privacybeleid beheert.

Welke data verzamelt Turf, en waar gaat die naartoe?

Per page view Turf stores, in your own database only: a one-way visitor hash,
timestamp, the page viewed, device type / browser / OS family (parsed from the
user-agent), language, country code (only if Cloudflare provides it), referrer
hostname, UTM parameters, scroll depth, and reading time. Raw event rows are
pruned automatically after 18 months (filterable); aggregate totals are kept.
Nothing is ever transmitted off your server.

Waarom zijn Turf’s cijfers lager dan die van Jetpack of een ruwe hitteller?

“Views” is deduplicated: a repeat view of the same page by the same visitor
within 30 minutes doesn’t count again (the same default Google Analytics and
Matomo use). The separate “Raw views” number counts every page load, for an
apples-to-apples comparison with hit-counting tools.

Werkt het samen met pagecaching?

Yes. Tracking runs client-side, so cached pages are still counted. Turf even
reports how much of your traffic is served from cache.

Waar komt de landdata vandaan?

From Cloudflare’s CF-IPCountry request header, if your site is behind
Cloudflare. Turf deliberately does not call any geolocation API – that would
mean sending visitor IPs to a third party. Without Cloudflare, country stays
empty unless you hook up your own local database via the turf_visitor_country
filter.

Verwijdert het verwijderen van de plugin mijn statistieken?

Standaard niet – analyticsgeschiedenis is waardevol, dus de data blijft bewaard bij het verwijderen/opnieuw installeren. Om alles te verwijderen bij deïnstallatie, voeg define( ‘TURF_REMOVE_DATA_ON_UNINSTALL’, true ); toe aan wp-config.php (of zet de optie turf_remove_data_on_uninstall op 1) voordat je de plugin verwijdert.

Where do I suggest a feature or report a bug?

Op de GitHub-repository van de plugin: https://github.com/fbloemhof/turf-stats/issues

Beoordelingen

Er zijn geen beoordelingen voor deze plugin.

Bijdragers & ontwikkelaars

“Turf Stats” is open source software. De volgende personen hebben bijgedragen aan deze plugin.

Bijdragers

Vertaal “Turf Stats” in je eigen taal.

Interesse in ontwikkeling?

Bekijk de code, haal de SVN repository op, of abonneer je op het ontwikkellog via RSS.

Changelog

1.26.0

  • Added “Load time trend” and “Time/visit trend” daily line charts to the
    Analysis page, next to the existing peak-hours heatmap.
  • Added a “PWA vs. browser” breakdown to the Statistics page: detects
    whether a pageview ran inside an installed PWA (Add to Home Screen /
    Install app) or a normal browser tab. This is a rough estimate of active
    PWA usage, not a hard install count – browsers don’t report installs to
    the server.

1.25.2

  • Reverted 1.25.1: “mln” for millions reads fine on Dutch sites too, so
    the “k”/”M” abbreviation is back to a plain, always-on suffix instead
    of going through translation.

1.25.1

  • Fixed: the abbreviated view/visitor counts added in 1.25.0 always showed
    the Dutch “mln” for millions, even on English (and other) sites. The
    “k”/”M” suffixes are now translatable, so non-Dutch locales show “1.2M”
    instead of “1,2 mln”.

1.25.0

  • Large view/visitor counts are now shown abbreviated (“12,3k”, “1,2 mln”)
    in the totals tiles, the [turf_stats] shortcode widget, and the view
    count shown to visitors on single posts – so big numbers keep fitting
    their fixed-width space. Tables and CSV exports still show exact figures.
  • Fixed the “Go to date” button showing the Dutch word “Toon” instead of
    “Show” for every locale except Dutch.

1.24.0

  • The Statistics page now loads noticeably faster: most boxes (device/
    browser/OS/country breakdowns, sources, UTM campaigns, top pages/terms,
    peak hours, etc.) load their data in the background right after the page
    appears, instead of making you wait for every query to finish first.
  • De zwaarste statistiek-queries worden nu een paar minuten gecachet, zodat het herladen van de pagina of het wisselen van periode niet telkens dezelfde trage databasequery herhaalt.
  • Visual refresh of the Statistics page: breakdown lists, the totals tiles,
    the daily chart, and report tables (top pages, top search terms, 404s,
    clicks, etc.) now share one consistent, more compact look with a hover
    highlight per row and a full-width bar behind each breakdown item instead
    of a separate small bar – including the Bots page’s breakdown, which now
    matches the rest of the plugin instead of using its own older style.
  • Nieuwe sorteerbare kolom “Weergaven” in de berichten-/paginalijst (en elk ander bijgehouden berichttype), zodat je weergaveaantallen ziet zonder de lijst te verlaten.
  • Opgelost: de tabellen “Van/Naar” (sessieroutes) en uitgaande links toonden hun tweede kolom rechts uitgelijnd in plaats van links.
  • Fixed the “Show more” toggle not working on boxes that load their data in
    the background.

1.23.0

  • Custom date ranges: pick any start/end date instead of just the fixed
    presets, and save frequently-used ranges by name to jump back to them
    later.
  • CSV export for the overview totals, top pages, top referrers,
    device/browser/OS breakdown, search terms, and 404s boxes – respects
    whatever period (including a custom range) is on screen.
  • Weekly/monthly email report: a summary of your stats sent to one or more
    addresses on a recurring schedule, with a “Send test email now” button to
    check formatting/delivery without waiting for the schedule.
  • Fixed several period-filtered boxes (404s, per-author stats, click and
    outbound-link breakdowns, WooCommerce funnel, peak-hours heatmap) silently
    including data all the way through “now” instead of stopping at the end
    of “Yesterday” or a picked date – only affected those two period choices,
    not the day/week/month tabs.
  • Dutch (nl_NL) translation updated for all new strings.

1.22.0

  • Track the utm_content campaign parameter (e.g. Instagram’s
    link_in_bio) alongside the existing utm_source/utm_medium/
    utm_campaign, with a matching “Campaign content (UTM)” breakdown box.

1.21.1

  • Fixed the “Formulieren” (Forms), “Top search terms” and “Most discussed”
    boxes on the Analysis/Statistics pages silently disappearing for any
    period other than “All time” – a broken date filter made the underlying
    query invalid SQL, so it failed silently and the box was dropped.

1.21.0

  • New [turf_stats] shortcode: an at-a-glance table (online now, today,
    yesterday, last 7 days, last 28 days) for a sidebar Text/HTML widget or
    Shortcode block, with metric (views/visitors), layout (table/list)
    and items attributes to customize which rows show.
  • Fixed a corrupted Dutch (nl_NL) .mo file (duplicate “Online now” source
    string made it fail to compile, and the compiled file itself wasn’t a
    valid sorted .mo) – Dutch translations were silently not loading.

1.20.3

  • Screen resolution breakdown labels are now English source strings with
    Dutch translations in the language file (was accidentally Dutch in code).
  • De berekening van het venster voor de dagelijkse grafiek is ondergebracht in een gedeelde helperfunctie turf_day_window(), zodat de vensters van één dag en 7 dagen de tijdzonelogica niet langer dupliceren.
  • Fixed TURF_VERSION (the cache-busting version for all enqueued JS/CSS)
    being stuck at 1.19.0 since the 1.20.0 release – every asset change since
    then was shipped under an unchanged version string.

1.20.2

  • Fixed daily bar chart on the Today/Yesterday/fixed-date tabs: it showed
    only the anchor day (plus a sliver of the day before under a non-UTC site
    timezone) instead of the intended 7-day context window. The chart query
    now spans the 7 days ending on the selected day, matching the 7 bars it
    renders. Regression from 1.20.0 (date navigation).

1.20.1

  • Screen resolution: fall back to viewport innerWidth/innerHeight in the
    tracking JS when window.screen reports 0 or is missing (in-app webviews,
    fingerprinting-protected browsers) so fewer views land in “unknown”.
  • Screen resolution breakdown now separates App/REST API views (which never
    run the tracking JS and legitimately have no screen size) from real browser
    views that failed to report one, instead of lumping both into a single
    “unknown” bucket.

1.20.0

  • Added date navigation (native date picker, Yesterday tab) with fixed-date sentinel fix.
  • Added top-referrers ‘Toon meer’ toggle (shows 10, reveals up to 50).
  • Dashboardwidget toegevoegd (nu online, weergaven/bezoekers van vandaag met % t.o.v. gisteren), met hergebruik van de vormgeving van de overzichtskaarten.
  • Added review-nudge snooze (random 30-90 days, max 3x then permanent).
  • Apparaatklasse-label toegevoegd (Telefoon/Tablet/Desktop) bij schermresolutie.
  • Opgelost: overflow in de 90-dagengrafiek (gat + horizontale scroll).
  • Dutch translations for new strings.

1.19.0

  • New “Screen resolution” breakdown box: visitor screen sizes (in CSS
    pixels) are recorded with each view. The new database columns are added
    automatically on update.
  • New “Avg. load time” stat box: page load times are measured in the
    visitor’s browser via the Navigation Timing API and averaged per period.
  • The “Online now” box gains a live “Currently viewed” list of the pages
    current visitors are on, refreshed on the same 20-second poll.
  • De uurgrafiek van bezoekers is herzien: een vaste 24-uursas met een gestippelde lijn voor “gisteren”, voor directe vergelijking met de vorige dag.
  • De dagelijkse balken voor weergaven/bezoekers tonen nu hun waarden in de grafiek, met een labelgrootte die zich aanpast aan de dichtheid bij de 30- en 90-dagenweergaven.
  • Het Cache-blok geeft nu een toelichting wanneer een cachelaag wordt gedetecteerd maar (bijna) geen van de gevolgde paginaweergaven serveert.
  • Much faster legacy view-count import: a Jetpack top-posts pre-pass
    covers the most-viewed posts in one request, admin-page batches run
    concurrently, and the WP-CLI command gains –offset/–limit flags.
  • Dutch (nl_NL) translation updated for all new strings.

1.18.1

  • Added wordpress.org listing screenshots (Statistics overview, Analysis,
    Bots & LLMs) and the corresponding == Screenshots == section. No
    functional or tracking changes.

1.18.0

  • De op GitHub gebaseerde updatecontrole is volledig verwijderd (updater.php en de meegeleverde library) – releases worden nu rechtstreeks naar WordPress.org gepubliceerd via een GitHub Action, en updates worden door wordpress.org afgehandeld zoals bij elke andere gehoste plugin.
  • Fixed postbox drag-order and collapse/expand state not actually being
    saved: the admin pages were missing the nonce fields WordPress core’s own
    postbox AJAX handlers look for, so those requests silently failed. Order
    and collapsed state now persist correctly per user.
  • De site-specifieke integratie met de begeleidende app “Dorpsapp” is nu een generiek, opt-in connector-app-mechanisme (turf_connector_app_route_patterns / turf_connector_app_label filters) – geen gedragsverandering, tenzij je het oude filter turf_dorpsapp_route_patterns gebruikte, dat is hernoemd.
  • Added a GitHub issues link (bug reports / feature suggestions) to the FAQ.
  • De import van oude weergaveaantallen (Jetpack Stats / de oude entry-views-plugin) is nu ook beschikbaar als beheerpagina “Statistieken > Importeren”, naast het bestaande WP-CLI-commando wp turf-stats import-legacy-views – dezelfde import, uitgevoerd in kleine AJAX-batches met een voortgangsbalk in plaats van de commandoregel.

1.17.2

  • Opgelost: een WordPress.org indieningsfout doordat de headers Plugin URI en Author URI naar dezelfde URL wezen. Author URI wijst nu naar het GitHub-profiel van de auteur in plaats van naar de plugin-repository.

1.17.1

  • Cleared the remaining WordPress.org Plugin Check warnings: dropped the
    now-redundant load_plugin_textdomain() call (translations for wp.org-hosted
    plugins load automatically since WP 4.6) and annotated the opt-in REST debug
    logger. No functional or tracking changes.

1.17.0

  • WordPress.org compliance-release: readme.txt, uninstall.php met opt-in dataverwijdering, directe-toegangsbeveiliging op alle bestanden, en de GitHub-updatecontrole maakt geen deel meer uit van de WordPress.org build (updates komen van wordpress.org).

1.16.1

  • Lange lijsten worden nu vóór de eerste weergave ingeklapt (CSS), waardoor de laadtijdsprong die in 1.16.0 werd geïntroduceerd, is verdwenen.

1.16.0

  • Inzicht in cache-offload (% vanuit cache geserveerd, met laagdetectie).
  • Rapportage landingspagina’s met bounce percentage per landingspagina.
  • Blokken zonder data voor de geselecteerde periode worden volledig verborgen.
  • All lists use one in-place Show more / Show less toggle; server-side
    pagination removed.

1.15.0

  • Bilingual: English source strings with a bundled Dutch (nl_NL) translation.

1.14.0

  • Raw (non-deduplicated) view counting, views per visitor, average visit
    duration, an hourly visitors chart for “Today”, and full-URL outbound link
    tracking including the source page.

Eerder

  • Zie https://github.com/fbloemhof/turf-stats/releases voor de volledige geschiedenis.