Privacy-first site analytics for your LaraClassifier / JobClass site. Track page views, unique visitors, referrers, countries, browsers, platforms, search keywords, and marketing campaigns, without third-party scripts or cookies.

Page View Tracking

Automatically records every front-end page visit via middleware. No manual instrumentation required.

Unique Visitors

Privacy-friendly unique visitor tracking using hashed IP + User-Agent fingerprints. No cookies needed.

Geographic Insights

Resolve visitor IPs to countries using the core GeoIP library with pluggable drivers.

Traffic Sources

Track referrer domains and URLs to understand where your traffic comes from.

Browser & Platform

Built-in User-Agent parser detects browser, OS platform, and device type (desktop/mobile/tablet).

UTM Campaign Tracking

Automatically captures UTM parameters (source, medium, campaign, term, content) from incoming URLs.

Dashboard Widget

At-a-glance traffic metrics injected directly into the admin dashboard with trend charts.

Use Cases

Portfolio or Agency Site

You run a portfolio site and want to understand which projects attract the most attention.

  • See which portfolio pages get the most views and from which countries.
  • Identify top referrer domains driving traffic to your site.
  • Track daily and weekly trends without relying on Google Analytics or other third-party tools.

Content-Driven Site with Blog

You publish articles and want to measure their performance over time.

  • Compare page views across different time periods (7 days, 30 days, 90 days, 1 year).
  • Identify the browsers and platforms your audience uses to optimize for compatibility.
  • Use the device type breakdown (desktop vs. mobile vs. tablet) to prioritize responsive design efforts.

Privacy-Conscious Organization

You need basic analytics without embedding third-party tracking scripts or setting cookies.

  • All data stays on your own server: no external API calls for tracking (GeoIP is optional).
  • Visitor uniqueness is determined via a hashed fingerprint, not cookies or persistent identifiers.
  • Configurable data retention automatically purges old records.

Requirements

  • LaraClassifier / JobClass v19.0.0 or later
  • PHP 8.3+
  • The Laravel scheduler (the site cron job) running, for the nightly data purge and the weekly crawler IP refresh
No external dependencies: The add-on works entirely standalone. GeoIP country detection uses the core GeoIP library already included in the core.

Installation

Step 1: Upload the add-on

Go to Admin panel → Extensions → Add-ons, click Upload add-on and drop the add-on's .zip file into the upload area (50 MB maximum). The archive is extracted into extensions/addons/stats/ and Site Statistics appears in the list, deactivated.

Cannot upload from the browser? Unzip the archive on your computer and copy the add-on folder to extensions/addons/stats/ over FTP or SSH: its addon.json file must sit directly inside that folder. Then open Admin panel → Extensions → Add-ons. The page scans extensions/addons/ every time it loads, so the add-on is listed straight away (the Sync button runs the same scan on demand).

Step 2: Activate the add-on

Click Activate on the Site Statistics card. It is a paid add-on, so a dialog asks for its purchase code, which is verified before anything else happens: an invalid code is rejected in the dialog and nothing is changed.

Once the code is accepted, activation runs in one pass: it creates the add-on's database tables (its migrations), registers its permissions, runs its seeders and publishes its public assets. Reload the page to see its new entry in the Add-ons section of the admin sidebar.

Step 3: Configure

Open Admin panel → Statistics from the Add-ons section of the sidebar and set the add-on up: see Configuration.

Purchase Code (License Key)

Site Statistics is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate Site Statistics in Admin panel → Extensions → Add-ons.

Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.

Platform / Marketplace How you get the purchase code Where to find it again
bedigit.com Store
In-site purchase (Shop)
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. My Account → My Licenses on bedigit.com
Gumroad Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com
Envato Market
CodeCanyon
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. Envato account → Downloads → License certificate & purchase code
Check your spam folder. For both bedigit.com Store and Gumroad purchases, the purchase code is delivered by email. Automated license emails are very often filtered, so if the message is not in your inbox, look in your spam / junk folder before contacting support, and add our sender address to your contacts or allow list.

1. bedigit.com Store (in-site purchase)

  • As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
  • It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
  • The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
  • The matching invoice is under My Account → My Orders.

2. Gumroad

  • A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
  • The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
  • When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library → your purchase on gumroad.com.
  • Use the same email address on bedigit.com as on Gumroad: your keys are then linked to your account automatically and listed under My Account → My Licenses, even if you register after the purchase. You can also add a Gumroad key manually from My Account → My Gumroad Licenses.

3. Envato Market (CodeCanyon)

  • Envato purchase codes are issued and delivered by Envato Market, never emailed by us, so there is nothing to look for in your spam folder: you retrieve the code from your Envato account.
  • Log in to your Envato / CodeCanyon account, open the Downloads page, find the item, and choose License certificate & purchase code from the Download dropdown. The code is written in that certificate.
  • An Envato purchase code looks like 12345678-90ab-cdef-1234-567890abcdef (8-4-4-4-12 characters). It never changes, and renewing item support does not issue a new one.
  • Official Envato article: Where Is My Purchase Code?
Lost your purchase code? Search your mailbox (spam folder included) for “license” or “purchase code”, then check My Account → My Licenses on bedigit.com for Store and Gumroad purchases, or Downloads → License certificate on Envato. If it is still missing, open a ticket on our Help Center with your order number (Store), Gumroad sale ID or buyer email (Gumroad), or Envato username and item name (Envato).

Configuration

All settings are managed in Admin panel → Statistics → Settings (in the Add-ons section of the sidebar) and saved in the settings table under the keys below. A key that was never saved falls back to the default from the add-on's config/stats.php file.

Setting Description Default
stats_enabled Master switch to enable or disable page view tracking. When disabled, no new data is collected, but existing data remains accessible. true
stats_retention_days Number of days to keep page view data. Older records are purged automatically every night at 03:00 (stats:purge). Set to 0 to keep data indefinitely. 90
stats_exclude_bots Keep detected bot traffic out of the reports. Detection combines known crawler User-Agents, the published search-engine IP ranges (Google and Bing feeds refreshed weekly) and the checks below. true
stats_store_bots Keep bot hits in the database, flagged with the reason they were caught, so the settings page can show the filtered share. They never appear in the reports. Off discards them on arrival. true
stats_bot_detect_fake_browser Flag clients that send a real browser User-Agent without the headers that browser always sends (Sec-Fetch-*, Accept-Language, Accept). true
stats_bot_detect_datacenter Flag visits coming from cloud and hosting provider networks. true
stats_bot_extra_ip_ranges Extra networks to treat as datacenter traffic, one CIDR range (or single IP) per line. AWS, Google Cloud and Azure are not filtered by default. (empty)
stats_exclude_admins Exclude logged-in admin users from being tracked. true
stats_exclude_my_ip Do not track visits from the IP address you are using when you save the settings page. false
stats_exclude_ips IP addresses (IPv4 or IPv6) whose visits are never tracked, one per line. (empty)
stats_track_unique Track unique visitors using a SHA-256 hash of IP + User-Agent (privacy-friendly, no cookies). true
stats_geoip_enabled Resolve visitor IP addresses to countries and cities using the GeoIP driver selected in Admin panel → Configuration → Settings → Localization. The MaxMind database is used as a fallback when its file is available on the server. true
stats_per_page Number of rows shown per page in admin statistics tables (10, 15, 25, 50 or 100). 25
stats_utm_tracking_enabled Enable automatic capture of UTM parameters (source, medium, campaign, term, content) from incoming URLs. true
Config file: The file config/stats.php provides defaults. Database settings (saved via the admin panel) always take precedence over config file values.

Environment Variables

Recording a page view is handed to a queued job that runs after the response is sent. Two optional .env keys choose where that job goes:

  • STATS_QUEUE_CONNECTION: the queue connection to use (default: the application's default connection). With database or redis and a running queue worker, the writes leave the web process entirely.
  • STATS_QUEUE_NAME: the queue name (default: default).

Admin: Overview Dashboard

The overview page (Statistics → Overview) provides a comprehensive snapshot of your site’s traffic. All views accept a ?period= query parameter to change the time range.

Period Selector

A dropdown button available on all statistics pages lets you switch between time periods:

Value Label
7dLast 7 days
30dLast 30 days (default)
90dLast 90 days
365dLast 365 days

Dashboard Widget

A traffic summary widget is automatically injected into the main admin dashboard. It displays:

  • Today’s Views: total page views for the current day
  • Today’s Unique Visitors: unique visitor count for the current day
  • This Week’s Views: total views for the current week
  • This Month’s Views: total views for the current month
  • Trend indicator: percentage change vs. yesterday
  • Mini chart: 30-day traffic chart (desktop) / 7-day chart (mobile)

Overview Charts & Metrics

The full overview page includes:

  • Summary cards: Total Views and Unique Visitors for the selected period
  • Traffic chart: stacked bar chart showing views vs. unique visitors over time
  • Top 10 Pages: most viewed pages with view counts
  • Top 10 Referrers: top referrer domains driving traffic
  • Top 10 Countries: countries by view count
  • Top 10 Browsers: browser distribution
  • Device type breakdown: desktop, mobile, and tablet proportions shown as progress bars
  • Top Platforms: OS distribution (Windows, macOS, Linux, Android, iOS, etc.)

Admin: Reports

Each report provides a dedicated, paginated view for a specific data dimension. All reports support the period selector and respect the stats_per_page setting.

Pages Report

Route: Statistics → Pages

A paginated table of all tracked page paths showing:

  • Rank: position by total views
  • Path: the URL path (e.g. /about, /portfolio/my-project)
  • Views: total page views in the selected period
  • Unique Visitors: unique visitor count for that page

Referrers Report

Route: Statistics → Referrers

A paginated table of referrer domains showing:

  • Rank: position by total hits
  • Domain: the referring domain (e.g. google.com, twitter.com)
  • Hits: number of referral visits

Countries Report

Route: Statistics → Countries

A paginated table of visitor countries showing:

  • Rank: position by total views
  • Country: ISO country code badge + country name
  • Views: total views from that country
  • Unique Visitors: unique visitors from that country
Note: Country data is only available when stats_geoip_enabled is set to true and the core GeoIP library is properly configured.

Cities Report

Route: Statistics → Cities

A paginated table of visitor cities, with a country filter and a city search, showing:

  • Rank: position by total views
  • City: the city name
  • Country: the country the city belongs to
  • Views: total views from that city
  • Unique Visitors: unique visitors from that city

The Pages viewed action on a row lists the pages visited from that city. Like the Countries report, it needs GeoIP to be enabled and configured.

Browsers Report

Route: Statistics → Browsers

A paginated table of detected browsers showing:

  • Rank: position by total views
  • Browser: browser name with icon (Chrome, Safari, Firefox, Edge, etc.)
  • Share: percentage of total views, displayed as a progress bar
  • Views: total views for that browser

Platforms Report

Route: Statistics → Platforms

A paginated table of detected operating systems showing:

  • Rank: position by total views
  • Platform: OS name with icon (Windows, macOS, Linux, Android, iOS, Chrome OS)
  • Share: percentage of total views, displayed as a progress bar
  • Views: total views for that platform

Admin: Keywords

The Keywords section (Statistics → Keywords) provides insight into how visitors find your site through UTM parameter tracking (marketing campaigns).

UTM Parameter Tracking

UTM tracking automatically captures marketing campaign parameters from incoming URLs. When a visitor arrives via a URL containing UTM parameters (e.g., ?utm_source=newsletter&utm_campaign=spring_sale), the data is recorded and displayed in the Keywords section.

Tracked Parameters

Parameter Description Example
utm_source Traffic source (required for tracking to activate) google, newsletter, facebook
utm_medium Marketing medium cpc, email, social
utm_campaign Campaign name spring_sale, product_launch
utm_term Search term or keyword web+design, laravel+cms
utm_content Ad or link variant (for A/B testing) banner_v1, sidebar_link

Reports

UTM data is available in two dedicated tabs within the Keywords section:

  • UTM Terms: shows all tracked utm_term values with visit counts, sources, and landing pages
  • UTM Campaigns: shows all tracked utm_campaign values with visit counts, sources, and mediums

The overview page also shows summary cards with total UTM visits and unique UTM visitors for the selected period.

How it works: UTM tracking is handled by the same middleware that records page views. When utm_source is present in the URL, a record is created in the stats_utm_visits table and daily aggregates are updated in stats_utm_daily. No cookies or JavaScript are involved.
Data retention: UTM data follows the same retention policy as page views. When old page view records are purged, the corresponding UTM visit records are also removed.

Admin: Settings

The settings page (Admin panel → Statistics → Settings) is organized into four tabs:

Tracking

  • Enable Tracking: master switch to start/stop data collection (existing data is kept)
  • Track Unique Visitors: count unique visitors with a SHA-256 hash of IP + User-Agent (no cookies)
  • Enable Country Detection: resolve IPs to countries with the GeoIP driver selected in Admin panel → Configuration → Settings → Localization

Privacy & Filtering

  • Exclude Bots & Crawlers: keep detected bot traffic out of the reports. The tab shows when the Google/Bing crawler IP feeds were last refreshed, with buttons to view the cached ranges and to refresh them now.
  • Store Bot Hits: keep filtered hits in the database, flagged with their reason. The tab then shows the share of traffic filtered in the last 7 days and the top reasons.
  • Detect Fake Browsers and Ignore Datacenter Traffic: the behavioural checks described above.
  • Additional IP Ranges: extra CIDR ranges to treat as datacenter traffic, one per line.
  • Exclude Admin Users: don’t track logged-in admin users
  • Exclude My Current IP Address: don’t track your current IP (captured when you save the page)
  • Exclude IP Addresses: one IPv4 or IPv6 address per line

The bot checks only apply to new traffic. To re-classify page views already recorded and rebuild the reports, run php artisan stats:reclassify-bots --recompute --force on the server (without --force it only reports what it would change). The tab ends with a Privacy Notice reminding administrators that the add-on loads no third-party scripts, sets no cookies and hashes visitor fingerprints.

Data Management

  • Data Retention (days): dropdown to select retention period (Unlimited, 30, 60, 90, 180, 365, or 730 days)
  • Items Per Page: dropdown to select pagination size (10, 15, 25, 50, or 100 items)

UTM Tracking

Toggle to enable or disable automatic capture of UTM parameters from incoming URLs. When enabled, the tracking middleware extracts utm_source, utm_medium, utm_campaign, utm_term, and utm_content from visitor URLs.

Updating

An update only replaces the add-on's files. Its database tables and data, its settings, its activation state and its recorded purchase code are all kept, so do not deactivate or remove the add-on before updating it. Back up your database first all the same.

Method 1: Upload the new version (recommended)

  1. Download the latest .zip file of the add-on.
  2. Go to Admin panel → Extensions → Add-ons and click Upload add-on.
  3. Drop the .zip file into the upload area.
  4. Because Site Statistics is already installed, a prompt shows the installed version and the new one. Click Replace: the extensions/addons/stats/ folder is swapped for the new files. Cancelling the prompt discards the upload.

Method 2: Replace the files by hand

  1. Over FTP or SSH, delete the extensions/addons/stats/ folder and upload the new one in its place. Replace the whole folder rather than copying over it, so files dropped by the new version do not linger.
  2. Open Admin panel → Extensions → Add-ons: the page re-reads addon.json and the card shows the new version number.

After the files are replaced

New database tables or columns. When a new version adds some, create them by running php artisan migrate --force over SSH, or without SSH by clicking Deactivate then Activate on the add-on's card: activation runs every pending migration (and asks for the purchase code again). Your data is not touched either way.

If your installation caches its configuration or routes (php artisan config:cache, route:cache), run php artisan optimize:clear after the update.

Uninstallation

Switching an add-on off without losing anything is a deactivation: go to Admin panel → Extensions → Add-ons, click Deactivate on the Site Statistics card and confirm.

  • The add-on is no longer loaded: its routes, views, admin sidebar entry and front-end pages stop answering.
  • Its database tables and all the data they hold are kept, and its files stay under extensions/addons/stats/. Nothing is deleted.
  • Its permissions and its recorded purchase code stay in the database. Only Remove deletes them.
  • Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.

Click Activate on the same card to switch it back on. As for a first activation, the purchase code is asked for and verified again; then any pending migrations run, the assets are republished, and the add-on picks up exactly where it left off.

Removing

Removing is permanent and destroys the add-on's data. The Remove button only appears on a deactivated add-on, so removal is always two steps:

  1. Deactivate Site Statistics (see Uninstallation).
  2. Click Remove on its card and confirm the prompt.

The admin panel then, in one pass:

  • runs the add-on's uninstall hook, if it ships one, while its code is still on disk;
  • revokes the permissions declared in its addon.json;
  • rolls back its migrations (this drops its database tables and every row they hold) and purges its entries from the migrations table, so a later reinstall migrates from scratch;
  • deletes its published assets: public/addons/stats/, public/vendor/stats/ and storage/app/public/addons/stats/;
  • deletes the add-on directory extensions/addons/stats/;
  • deletes its row in the addons table (the recorded purchase code goes with it) and clears the application cache.
This cannot be undone. Back up your database before removing an add-on whose data you may still need: installing it again later creates empty tables, not your old content, and asks for the purchase code again.

Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/stats/. In that last case, give that user write permission on the directory and on its parent, then try again.

Deleting the folder over FTP or SSH is not equivalent: the add-on is only switched off, and its tables, its entries in the migrations table and its addons row are all left behind. Use Remove in the admin panel instead.

Troubleshooting

No data is being recorded

  • Check that stats_enabled is set to true in Statistics → Settings.
  • Verify the add-on is activated in Admin panel → Extensions → Add-ons.
  • If you are logged in as an admin, check that stats_exclude_admins is not enabled (or test in a private/incognito browser window).
  • Check that your IP address is not excluded (Exclude My Current IP Address or the Exclude IP Addresses list).
  • The stats_page_views table must exist: it is created when the add-on is activated.
  • If STATS_QUEUE_CONNECTION (or the application's default queue) points to a real queue, a queue worker must be running for the page views to be written.

Country data is missing or shows “Unknown”

  • Verify stats_geoip_enabled is true.
  • Check that the GeoIP driver is configured correctly in Admin panel → Configuration → Settings → Localization.
  • Local/private IPs (127.0.0.1, 192.168.x.x, etc.) cannot be resolved and will show as unknown.
  • If using an API-based GeoIP driver, check that the API key is valid and has not exceeded rate limits.
  • For production, consider using the MaxMind Database driver (maxmind_database) with the GeoLite2-City.mmdb file for reliable offline lookups.

Dashboard widget is not showing

  • The widget is registered by the add-on as a dashboard widget: ensure the add-on is active.
  • Check that the widget has not been hidden in the dashboard’s widget customization.
  • Verify the user has the admin.stats.view permission.

Statistics pages show “No data available”

  • If the add-on was just installed, wait for some front-end traffic to be recorded.
  • Try changing the period selector to a wider range (e.g. 90 days or 365 days).
  • Check if data retention has purged older records: adjust stats_retention_days if needed.

Bot traffic is inflating statistics

  • Enable Exclude Bots & Crawlers, Detect Fake Browsers and Ignore Datacenter Traffic on the Privacy & Filtering tab.
  • Add the networks of any remaining offenders to Additional IP Ranges.
  • With Store Bot Hits on, the tab shows the filtered share and its top reasons; the is_bot and bot_reason columns of stats_page_views can be reviewed too.
  • To clean up traffic recorded before a check was enabled, run php artisan stats:reclassify-bots --recompute --force.

UTM data is not being recorded

  • Check that stats_utm_tracking_enabled is set to true in Statistics → Settings.
  • UTM tracking requires at minimum the utm_source parameter in the URL. URLs without utm_source are ignored.
  • Verify URLs contain valid UTM parameters: ?utm_source=test&utm_term=keyword.
  • The main stats tracking must also be enabled (stats_enabled) for UTM tracking to work.

High database storage usage

  • Reduce the stats_retention_days setting to a shorter period.
  • The daily scheduled task at 3:00 AM automatically purges old data (stats:purge). Ensure the site cron job runs the Laravel scheduler (php artisan schedule:run every minute).
  • The stats_page_views table grows fastest. Aggregate tables (stats_daily, etc.) are much smaller since they store one row per dimension per day.

Performance concerns with high traffic

  • The middleware hands the writes to a queued job dispatched after the response is sent, so it does not add latency to page loads. Set STATS_QUEUE_CONNECTION to database or redis and run a queue worker to move that work out of the web process.
  • All statistics queries use aggregate tables with proper indexes, not the raw stats_page_views table.
  • For very high traffic sites, consider reducing retention to 30 days and using the offline MaxMind GeoIP driver to avoid external API calls.

Site Statistics v1.0.5: A LaraClassifier / JobClass add-on.

© BeDigit. All rights reserved.

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket