{"id":388209,"date":"2026-10-21T03:59:51","date_gmt":"2026-10-21T03:59:51","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/visitrix-lightweight-visitor-analytics\/"},"modified":"2026-10-22T14:31:54","modified_gmt":"2026-10-22T14:31:54","slug":"visitrix","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/visitrix\/","author":23451213,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.5.0","stable_tag":"1.5.0","tested":"7.1.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Visitrix \u2013 Lightweight Visitor Analytics","header_author":"genius-bot.ru","header_description":"Lightweight, privacy-friendly visitor statistics: traffic sources, search engines, devices, browsers, time on site and bounce rate. All data stays in your database.","assets_banners_color":"8abbf5","last_updated":"2026-10-22 14:31:54","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/genius-bot.ru\/plugins\/#donat","header_plugin_uri":"https:\/\/genius-bot.ru\/plugins\/visitrix\/","header_author_uri":"https:\/\/genius-bot.ru","rating":0,"author_block_rating":0,"active_installs":10,"downloads":294,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.1":{"tag":"1.1.1","author":"akklex","date":"2026-10-21 03:59:39","revision":3757679},"1.2.0":{"tag":"1.2.0","author":"akklex","date":"2026-10-21 08:43:05","revision":3757964},"1.2.1":{"tag":"1.2.1","author":"akklex","date":"2026-10-21 09:23:10","revision":3758021},"1.3.0":{"tag":"1.3.0","author":"akklex","date":"2026-10-22 02:35:30","revision":3759251},"1.3.1":{"tag":"1.3.1","author":"akklex","date":"2026-10-22 09:41:22","revision":3759635},"1.4.0":{"tag":"1.4.0","author":"akklex","date":"2026-10-22 10:27:38","revision":3759704},"1.5.0":{"tag":"1.5.0","author":"akklex","date":"2026-10-22 14:31:54","revision":3760081}},"upgrade_notice":{"1.5.0":"<p>Optional ClickHouse storage (ClickHouse Cloud, Yandex Cloud, your own server). Nothing changes until you enable it.<\/p>","1.4.0":"<p>Optional separate MySQL\/MariaDB database for the statistics, including cloud databases. Nothing changes until you enable it.<\/p>","1.3.0":"<p>Goals without setup, scroll map and content reports.<\/p>","1.2.1":"<p>Lower server load: lightweight beacon handler and fewer pings.<\/p>","1.2.0":"<p>More accurate new and returning visitors, robot filter, consent support and &quot;Online now&quot;.<\/p>","1.1.1":"<p>Compatibility improvements for the WordPress.org directory.<\/p>","1.1.0":"<p>Adds the new and returning visitors report.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3757678,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3757678,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3757678,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3757678,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3761008,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=visitrix\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"features\":{\"networking\":false},\"login\":true,\"steps\":[{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"visitrix\"},\"options\":{\"activate\":true}},{\"step\":\"runPHP\",\"code\":\"<?php\\n\\\/**\\n * Visitrix live preview: demo content and two weeks of statistics.\\n *\\\/\\nrequire '\\\/wordpress\\\/wp-load.php';\\n\\nglobal $wpdb;\\nmt_srand( 20261023 );\\n\\n\\\/\\\/ Posts in categories, so the content report has something to show.\\n$cats = array();\\nforeach ( array( 'Guides', 'News', 'Reviews' ) as $name ) {\\n\\t$term   = wp_insert_term( $name, 'category' );\\n\\t$cats[] = is_wp_error( $term ) ? (int) $term->get_error_data() : (int) $term['term_id'];\\n}\\n$titles = array( 'How to choose a theme', 'Ten tips for faster pages', 'Our spring update', 'Best plugins for small shops', 'A beginner guide to SEO', 'Contact form that converts' );\\n$pages  = array( array( '\\\/', 'Home', 0 ) );\\nforeach ( $titles as $i => $title ) {\\n\\t$id = wp_insert_post(\\n\\t\\tarray(\\n\\t\\t\\t'post_title'    => $title,\\n\\t\\t\\t'post_status'   => 'publish',\\n\\t\\t\\t'post_author'   => 1,\\n\\t\\t\\t'post_category' => array( $cats[ $i % 3 ] ),\\n\\t\\t\\t'post_content'  => str_repeat( \\\"<p>Visitrix counts visits, sources, goals and how far people scroll.<\\\/p>\\\\n\\\", 40 ),\\n\\t\\t)\\n\\t);\\n\\t$pages[] = array( wp_make_link_relative( get_permalink( $id ) ), $title, $id );\\n}\\n$pages[] = array( '\\\/contact\\\/', 'Contact', 0 );\\n$pages[] = array( '\\\/pricing\\\/', 'Pricing', 0 );\\n\\n$p       = $wpdb->prefix . 'visitrix_';\\n$sources = array(\\n\\tarray( 'search', 'Google', 'https:\\\/\\\/www.google.com\\\/', 30 ),\\n\\tarray( 'search', 'Yandex', 'https:\\\/\\\/yandex.ru\\\/', 18 ),\\n\\tarray( 'search', 'Bing', 'https:\\\/\\\/www.bing.com\\\/', 4 ),\\n\\tarray( 'direct', '', '', 20 ),\\n\\tarray( 'social', 'Facebook', 'https:\\\/\\\/facebook.com\\\/', 6 ),\\n\\tarray( 'social', 'VK', 'https:\\\/\\\/vk.com\\\/', 5 ),\\n\\tarray( 'messenger', 'Telegram', 'https:\\\/\\\/t.me\\\/', 7 ),\\n\\tarray( 'ai', 'ChatGPT', 'https:\\\/\\\/chatgpt.com\\\/', 4 ),\\n\\tarray( 'ad', 'Google Ads', '', 3 ),\\n\\tarray( 'referral', 'example.org', 'https:\\\/\\\/example.org\\\/blog\\\/', 3 ),\\n);\\n$devices = array( array( 'mobile', 'Chrome', 'Android', 38 ), array( 'mobile', 'Safari', 'iOS', 22 ), array( 'desktop', 'Chrome', 'Windows', 22 ), array( 'desktop', 'Safari', 'macOS', 8 ), array( 'desktop', 'Firefox', 'Windows', 4 ), array( 'desktop', 'Edge', 'Windows', 4 ), array( 'tablet', 'Safari', 'iOS', 2 ) );\\n$goals   = array( array( 'form', 'contact-form' ), array( 'tel', '+1 555 0100' ), array( 'email', 'hello@example.com' ), array( 'messenger', 't.me\\\/example' ), array( 'download', 'price-list.pdf' ), array( 'outbound', 'github.com' ) );\\n$pick    = static function ( $list ) {\\n\\t$total = array_sum( array_column( $list, 3 ) );\\n\\t$r     = mt_rand( 1, $total );\\n\\tforeach ( $list as $item ) {\\n\\t\\t$r -= $item[3];\\n\\t\\tif ( $r <= 0 ) {\\n\\t\\t\\treturn $item;\\n\\t\\t}\\n\\t}\\n\\treturn $list[0];\\n};\\n\\n$visitors = array();\\nfor ( $i = 0; $i < 900; $i++ ) {\\n\\t$visitors[] = md5( 'demo-visitor-' . $i );\\n}\\n$now   = current_time( 'timestamp' );\\n$seen  = array();\\n$known = array();\\nfor ( $day = 13; $day >= 0; $day-- ) {\\n\\t$date  = gmdate( 'Y-m-d', $now - $day * DAY_IN_SECONDS );\\n\\t$wday  = (int) gmdate( 'N', strtotime( $date ) );\\n\\t$count = ( $wday >= 6 ? 55 : 90 ) + mt_rand( 0, 25 ) + ( 13 - $day ) * 2;\\n\\tif ( 0 === $day ) {\\n\\t\\t$count = (int) max( 12, $count * ( (int) gmdate( 'G', $now ) + 1 ) \\\/ 24 );\\n\\t}\\n\\tfor ( $n = 0; $n < $count; $n++ ) {\\n\\t\\t$hour = (int) round( 9 + 13 * ( mt_rand( 0, 1000 ) \\\/ 1000 ) ** 1.3 ) % 24;\\n\\t\\tif ( 0 === $day ) {\\n\\t\\t\\t\\\/\\\/ Today: spread over the hours that have passed, so the chart does not drop to zero.\\n\\t\\t\\t$hour = mt_rand( 0, max( 0, (int) gmdate( 'G', $now ) ) );\\n\\t\\t}\\n\\t\\t$start = strtotime( $date . ' 00:00:00' ) + $hour * 3600 + mt_rand( 0, 3599 );\\n\\t\\tif ( $start > $now ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\t$vk           = $visitors[ mt_rand( 0, mt_rand( 0, 1 ) ? 899 : 250 ) ];\\n\\t\\t$src          = $pick( $sources );\\n\\t\\t$dev          = $pick( $devices );\\n\\t\\t$views        = mt_rand( 1, 100 ) <= 47 ? 1 : mt_rand( 2, 6 );\\n\\t\\t$dur          = 1 === $views ? ( mt_rand( 1, 100 ) <= 70 ? mt_rand( 2, 14 ) : mt_rand( 15, 120 ) ) : mt_rand( 40, 900 );\\n\\t\\t$landing      = $pages[ mt_rand( 0, count( $pages ) - 1 ) ];\\n\\t\\t$is_new       = isset( $known[ $vk ] ) ? 0 : 1;\\n\\t\\t$known[ $vk ] = 1;\\n\\t\\t$utm          = 'ad' === $src[0] ? array( 'google', 'cpc', 'spring_sale' ) : ( 'messenger' === $src[0] && mt_rand( 0, 1 ) ? array( 'telegram', 'post', 'launch' ) : array( '', '', '' ) );\\n\\t\\t$wpdb->insert(\\n\\t\\t\\t$p . 'visits',\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'visit_key'    => md5( 'demo-visit-' . $start . '-' . $n ),\\n\\t\\t\\t\\t'visitor_key'  => $vk,\\n\\t\\t\\t\\t'started_at'   => gmdate( 'Y-m-d H:i:s', $start ),\\n\\t\\t\\t\\t'ts_start'     => $start,\\n\\t\\t\\t\\t'ts_last'      => $start + $dur,\\n\\t\\t\\t\\t'duration'     => $dur,\\n\\t\\t\\t\\t'pageviews'    => $views,\\n\\t\\t\\t\\t'is_new'       => $is_new,\\n\\t\\t\\t\\t'engaged'      => 1,\\n\\t\\t\\t\\t'id_type'      => 's',\\n\\t\\t\\t\\t'source_type'  => $src[0],\\n\\t\\t\\t\\t'source_name'  => $src[1],\\n\\t\\t\\t\\t'referrer'     => $src[2],\\n\\t\\t\\t\\t'landing'      => $landing[0],\\n\\t\\t\\t\\t'utm_source'   => $utm[0],\\n\\t\\t\\t\\t'utm_medium'   => $utm[1],\\n\\t\\t\\t\\t'utm_campaign' => $utm[2],\\n\\t\\t\\t\\t'device'       => $dev[0],\\n\\t\\t\\t\\t'browser'      => $dev[1],\\n\\t\\t\\t\\t'os'           => $dev[2],\\n\\t\\t\\t)\\n\\t\\t);\\n\\t\\t$visit_id = (int) $wpdb->insert_id;\\n\\t\\t$path     = $landing;\\n\\t\\tfor ( $v = 0; $v < $views; $v++ ) {\\n\\t\\t\\tif ( $v > 0 ) {\\n\\t\\t\\t\\t$path = $pages[ mt_rand( 0, count( $pages ) - 1 ) ];\\n\\t\\t\\t}\\n\\t\\t\\t$wpdb->insert(\\n\\t\\t\\t\\t$p . 'hits',\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'visit_id'   => $visit_id,\\n\\t\\t\\t\\t\\t'created_at' => gmdate( 'Y-m-d H:i:s', $start + (int) ( $dur * $v \\\/ max( 1, $views ) ) ),\\n\\t\\t\\t\\t\\t'path'       => $path[0],\\n\\t\\t\\t\\t\\t'title'      => $path[1],\\n\\t\\t\\t\\t\\t'post_id'    => $path[2],\\n\\t\\t\\t\\t\\t'scroll'     => min( 100, max( 10, (int) round( 100 - 90 * ( mt_rand( 0, 1000 ) \\\/ 1000 ) ** 0.7 ) ) ),\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\tif ( mt_rand( 1, 100 ) <= 9 ) {\\n\\t\\t\\t$g = $goals[ mt_rand( 0, count( $goals ) - 1 ) ];\\n\\t\\t\\t$wpdb->insert(\\n\\t\\t\\t\\t$p . 'goals',\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'visit_id'   => $visit_id,\\n\\t\\t\\t\\t\\t'created_at' => gmdate( 'Y-m-d H:i:s', $start + $dur ),\\n\\t\\t\\t\\t\\t'type'       => $g[0],\\n\\t\\t\\t\\t\\t'target'     => $g[1],\\n\\t\\t\\t\\t\\t'path'       => $path[0],\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\tif ( ! isset( $seen[ $vk ] ) ) {\\n\\t\\t\\t$seen[ $vk ] = array( $start, $start, 0 );\\n\\t\\t}\\n\\t\\t$seen[ $vk ][1] = $start;\\n\\t\\t++$seen[ $vk ][2];\\n\\t}\\n}\\nforeach ( $seen as $vk => $s ) {\\n\\t$wpdb->insert(\\n\\t\\t$p . 'visitors',\\n\\t\\tarray(\\n\\t\\t\\t'visitor_key' => $vk,\\n\\t\\t\\t'first_seen'  => gmdate( 'Y-m-d H:i:s', $s[0] ),\\n\\t\\t\\t'last_seen'   => gmdate( 'Y-m-d H:i:s', $s[1] ),\\n\\t\\t\\t'visits'      => $s[2],\\n\\t\\t)\\n\\t);\\n}\\n\"}]}"}},"all_blocks":[],"tagged_versions":["1.1.1","1.2.0","1.2.1","1.3.0","1.3.1","1.4.0","1.5.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3757678,"resolution":"1","location":"assets","locale":"","width":1500,"height":591},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3757678,"resolution":"2","location":"assets","locale":"","width":1500,"height":617},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3757678,"resolution":"3","location":"assets","locale":"","width":1500,"height":817}},"screenshots":{"1":"Traffic summary: key metrics with comparison to the previous period and the traffic chart.","2":"Traffic sources, device types, search engines and browsers.","3":"New and returning visitors and the detailed sources report."}},"plugin_section":[262246],"plugin_tags":[232,521,522,493,871],"plugin_category":[36,55],"plugin_contributors":[287813],"plugin_business_model":[],"class_list":["post-388209","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-analytics","plugin_tags-statistics","plugin_tags-stats","plugin_tags-traffic","plugin_tags-visitors","plugin_category-analytics","plugin_category-seo-and-marketing","plugin_contributors-akklex","plugin_committers-akklex"],"banners":{"banner":"https:\/\/ps.w.org\/visitrix\/assets\/banner-772x250.png?rev=3757678","banner_2x":"https:\/\/ps.w.org\/visitrix\/assets\/banner-1544x500.png?rev=3757678","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/visitrix\/assets\/icon-128x128.png?rev=3757678","icon_2x":"https:\/\/ps.w.org\/visitrix\/assets\/icon-256x256.png?rev=3757678","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/visitrix\/assets\/screenshot-1.png?rev=3757678","caption":"Traffic summary: key metrics with comparison to the previous period and the traffic chart."},{"src":"https:\/\/ps.w.org\/visitrix\/assets\/screenshot-2.png?rev=3757678","caption":"Traffic sources, device types, search engines and browsers."},{"src":"https:\/\/ps.w.org\/visitrix\/assets\/screenshot-3.png?rev=3757678","caption":"New and returning visitors and the detailed sources report."}],"raw_content":"<!--section=description-->\n<p>Visitrix gives you a clean, informative traffic summary right in the WordPress admin \u2013 without third-party services or heavy scripts, and without cookies by default. Open <strong>Statistics<\/strong> in the admin menu and see where your visitors come from, what devices they use and how engaged they are.<\/p>\n\n<p>Plugin homepage with screenshots and setup steps (in Russian): <a href=\"https:\/\/genius-bot.ru\/plugins\/visitrix\/\">genius-bot.ru\/plugins\/visitrix\/<\/a><\/p>\n\n<h4>What you get<\/h4>\n\n<ul>\n<li><strong>Key metrics<\/strong> \u2013 visits, visitors, pageviews, bounce rate, page depth, time on site and share of new visitors, each compared with the previous period.<\/li>\n<li><strong>Traffic chart<\/strong> \u2013 by hour for short periods, by day for longer ones. Toggle visits, visitors, pageviews and new visitors.<\/li>\n<li><strong>Traffic sources<\/strong> \u2013 direct traffic, search engines, social networks, messengers, AI assistants (ChatGPT, Perplexity, Gemini and others), links from other sites, ads (UTM tags, yclid, gclid) and internal traffic.<\/li>\n<li><strong>Search engines<\/strong> \u2013 Google, Yandex, Bing, DuckDuckGo, Mail.ru, Baidu and others.<\/li>\n<li><strong>New and returning visitors<\/strong> \u2013 bounce rate, page depth and time on site for each group, plus loyalty (how many times visitors came back).<\/li>\n<li><strong>Online now<\/strong> \u2013 visitors active during the last 5 minutes.<\/li>\n<li><strong>Devices<\/strong> \u2013 PC, smartphone or tablet, plus browsers and operating systems.<\/li>\n<li><strong>Goals without setup<\/strong> \u2013 form submissions (Contact Form 7, WPForms, Elementor and regular forms), clicks on phone numbers, e-mails and messengers, file downloads and outbound links, with conversion by traffic source.<\/li>\n<li><strong>Scroll map<\/strong> \u2013 see how far visitors scroll each page, right on top of the page, separately for PC, smartphones and tablets.<\/li>\n<li><strong>WordPress content<\/strong> \u2013 most read posts, categories, tags and authors, with read depth.<\/li>\n<li><strong>Content<\/strong> \u2013 popular pages, landing pages and UTM campaigns.<\/li>\n<li><strong>Periods<\/strong> \u2013 today, yesterday, 3 days, week, month or any custom date range.<\/li>\n<li><strong>Dashboard widget<\/strong> with today's numbers.<\/li>\n<\/ul>\n\n<h4>How metrics are calculated<\/h4>\n\n<ul>\n<li>A <strong>visit<\/strong> is a sequence of pageviews with no more than 30 minutes of inactivity. Arriving from a different external source starts a new visit.<\/li>\n<li>A <strong>bounce<\/strong> is a visit with a single pageview that lasted less than 15 seconds.<\/li>\n<li><strong>Time on site<\/strong> is measured with lightweight engagement pings while the page is visible.<\/li>\n<li>A <strong>new visitor<\/strong> is a visitor whose first visit falls within the selected period; everyone else is returning. Each visitor belongs to exactly one group.<\/li>\n<li>With the <strong>robot filter<\/strong> (on by default) a visit is counted after the first real interaction: scroll, tap, click, key press or a second pageview.<\/li>\n<\/ul>\n\n<h4>Lightweight<\/h4>\n\n<ul>\n<li>The tracker script is about 2 KB gzipped, loaded with <code>defer<\/code> and sent with <code>navigator.sendBeacon<\/code>, so it does not slow pages down.<\/li>\n<li>Beacons are handled right after plugins load \u2013 without the theme, <code>init<\/code> hooks or the REST API \u2013 so each hit costs a fraction of a page render.<\/li>\n<li>About 3 requests per pageview: the pageview, a ping at 15 seconds and one when the visitor leaves (plus one every 3 minutes on long reads).<\/li>\n<li>Works with page caching plugins \u2013 the front-end needs no nonces or PHP sessions.<\/li>\n<li>Compact database tables with automatic cleanup of old records.<\/li>\n<li>Optional separate database \u2013 MySQL\/MariaDB or ClickHouse \u2013 to keep the statistics out of the WordPress database (see below).<\/li>\n<li>The dashboard is plain JavaScript with built-in SVG charts \u2013 no external libraries, no CDN.<\/li>\n<\/ul>\n\n<h4>Visitor identification<\/h4>\n\n<p>Choose the mode that fits your privacy policy:<\/p>\n\n<ul>\n<li><strong>Without cookies<\/strong> (default) \u2013 a random anonymous ID in localStorage.<\/li>\n<li><strong>Accurate<\/strong> \u2013 the ID is also kept in a first-party HttpOnly cookie set by your own server. Returning visitors are recognized in Safari after 7+ days and across www\/non-www.<\/li>\n<li><strong>Anonymous<\/strong> \u2013 nothing is stored in the browser. Pageviews are grouped into visits with a hash of IP and user agent that changes daily; the IP itself is never stored.<\/li>\n<\/ul>\n\n<p>Works with the <strong>WP Consent API<\/strong>: until a visitor allows statistics in your cookie banner, their visits are counted in the anonymous mode.<\/p>\n\n<h4>Separate database (optional)<\/h4>\n\n<p>By default the statistics are stored in the WordPress database. On hosting with a small database quota, or to keep the statistics away from the site content, Visitrix can write them to a separate MySQL or MariaDB database:<\/p>\n\n<ul>\n<li>a second database of your hosting;<\/li>\n<li>a cloud MySQL-compatible database: Yandex Managed Service for MySQL, VK Cloud, Selectel, Timeweb Cloud, Amazon RDS and Aurora, Google Cloud SQL, Azure Database for MySQL, DigitalOcean, PlanetScale, TiDB Cloud and others.<\/li>\n<\/ul>\n\n<p>Or to <strong>ClickHouse<\/strong> \u2013 ClickHouse Cloud, Yandex Managed Service for ClickHouse, Altinity or your own server. Visitrix talks to it over the HTTP(S) interface, so no PHP extension is needed. ClickHouse stores an append-only event log; visits, pages and goals are assembled from it by views with the same rules as in MySQL, so the reports are identical. Old events expire automatically after the retention period (TTL).<\/p>\n\n<p>The connection is checked before it is saved, SSL\/TLS with your provider's CA certificate is supported for MySQL, and earlier statistics can be copied to the new database in one click, after which the WordPress tables can be emptied. If the external database becomes unreachable, visits are not recorded (they never fall back into the WordPress database) and a notice is shown on the Visitrix pages.<\/p>\n\n<h4>Privacy<\/h4>\n\n<ul>\n<li>No cookies by default; nothing at all is stored in the anonymous mode.<\/li>\n<li>IP addresses are not stored.<\/li>\n<li>All data stays in your own database (the WordPress one or a database you choose) and is never sent to third parties.<\/li>\n<li>Optional respect for the browser Do Not Track signal.<\/li>\n<li>Suggested text is added to the WordPress Privacy Policy guide.<\/li>\n<\/ul>\n\n<h4>Support the development<\/h4>\n\n<p>Visitrix is free and has no ads or paid limits. If it saves you time, you can thank the developer with a small donation on <a href=\"https:\/\/genius-bot.ru\/plugins\/#donat\">genius-bot.ru<\/a> \u2013 it helps release updates, translations and new free plugins.<\/p>\n\n<h3>Additional Information<\/h3>\n\n<h4>Developer<\/h4>\n\n<p>Visitrix is developed and maintained by <a href=\"https:\/\/genius-bot.ru\">genius-bot.ru<\/a>.<\/p>\n\n<ul>\n<li>Plugin page: <a href=\"https:\/\/genius-bot.ru\/plugins\/visitrix\/\">genius-bot.ru\/plugins\/visitrix\/<\/a><\/li>\n<li>Website: <a href=\"https:\/\/genius-bot.ru\">genius-bot.ru<\/a><\/li>\n<li>Telegram: <a href=\"https:\/\/t.me\/Alex_mlr_dev\">t.me\/Alex_mlr_dev<\/a> \u2013 questions, bug reports and feature requests.<\/li>\n<\/ul>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>WordPress 6.2 or later<\/li>\n<li>PHP 7.4 or later<\/li>\n<li>MySQL 5.7+ or MariaDB 10.3+<\/li>\n<li>WordPress REST API must be reachable (it is enabled by default)<\/li>\n<\/ul>\n\n<h4>Languages<\/h4>\n\n<p>Visitrix is fully translatable. Translations are delivered automatically from <a href=\"https:\/\/translate.wordpress.org\/projects\/wp-plugins\/visitrix\/\">translate.wordpress.org<\/a> \u2013 you can help translate it into your language.<\/p>\n\n<h4>Data stored<\/h4>\n\n<ul>\n<li><code>{prefix}visitrix_visits<\/code> \u2013 one row per visit: start time, duration, pageviews, source, landing page, UTM tags, device type, browser and OS.<\/li>\n<li><code>{prefix}visitrix_hits<\/code> \u2013 one row per pageview: page path and title.<\/li>\n<li><code>{prefix}visitrix_visitors<\/code> \u2013 one row per known visitor: anonymous ID, first and last visit, number of visits.<\/li>\n<li><code>{prefix}visitrix_goals<\/code> \u2013 one row per reached goal: type, target (form name, phone number, file, domain) and page.<\/li>\n<\/ul>\n\n<p>Records older than the retention period (365 days by default) are removed daily. With a separate database the same tables are created there with the prefix you choose; deleting the plugin never touches the external database.<\/p>\n\n<h4>Developer hooks<\/h4>\n\n<ul>\n<li><code>visitrix_should_track<\/code> (filter) \u2013 return <code>false<\/code> to skip tracking on the current page.<\/li>\n<li><code>visitrix_source_rules<\/code> (filter) \u2013 add or change search engines, social networks, messengers and AI services.<\/li>\n<li><code>visitrix_view_capability<\/code> (filter) \u2013 capability required to view reports.<\/li>\n<li><code>visitrix_client_ip<\/code> (filter) \u2013 client IP used for the anonymous daily hash (for sites behind a proxy).<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin from the <strong>Plugins \u2192 Add New<\/strong> screen, or upload the <code>visitrix<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin.<\/li>\n<li>Open <strong>Statistics<\/strong> in the admin menu. Data appears after the first visits.<\/li>\n<li>Optional: choose excluded roles and data retention in <strong>Statistics \u2192 Settings<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"are%20my%20own%20visits%20counted%3F\"><h3>Are my own visits counted?<\/h3><\/dt>\n<dd><p>By default, visits from logged-in administrators are not tracked. You can choose excluded roles in the settings. To test tracking, open the site in a private window.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20caching%20plugins%3F\"><h3>Does it work with caching plugins?<\/h3><\/dt>\n<dd><p>Yes. The tracker is a static script that sends data to the REST API, so cached pages are counted correctly.<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20cookie%20banner%3F\"><h3>Do I need a cookie banner?<\/h3><\/dt>\n<dd><p>Visitrix does not set cookies and does not store IP addresses, but it does store an anonymous identifier in localStorage. Requirements differ by country \u2013 please consult your legal adviser.<\/p><\/dd>\n<dt id=\"why%20are%20the%20numbers%20different%20from%20google%20analytics%20or%20yandex%20metrica%3F\"><h3>Why are the numbers different from Google Analytics or Yandex Metrica?<\/h3><\/dt>\n<dd><p>Every tool filters bots and counts sessions slightly differently. Visitrix counts only real browsers that execute JavaScript, and ad blockers usually do not block a first-party script, so numbers are often a bit higher.<\/p><\/dd>\n<dt id=\"why%20can%20a%20returning%20visitor%20be%20counted%20as%20new%3F\"><h3>Why can a returning visitor be counted as new?<\/h3><\/dt>\n<dd><p>The anonymous ID lives in the browser. A private window, cleared site data or another device make the visitor look new \u2013 other analytics tools have the same limitation. Safari also clears localStorage after 7 days without visits; switch to the <strong>Accurate<\/strong> mode in the settings to avoid that.<\/p><\/dd>\n<dt id=\"how%20do%20i%20exclude%20my%20own%20visits%3F\"><h3>How do I exclude my own visits?<\/h3><\/dt>\n<dd><p>Logged-in administrators are not counted by default. To exclude a device where you are not logged in (for example, your phone), open <strong>Statistics \u2192 Settings<\/strong> on it and click <strong>Do not count this browser<\/strong>.<\/p><\/dd>\n<dt id=\"which%20goals%20are%20tracked%3F\"><h3>Which goals are tracked?<\/h3><\/dt>\n<dd><p>Without any setup: form submissions (Contact Form 7 counts only successfully sent forms), clicks on <code>tel:<\/code> and <code>mailto:<\/code> links, links to Telegram, WhatsApp, Viber, VK and MAX, downloads of documents, archives and media files, and clicks on links to other sites. Search forms are not counted as goals. The contents of forms are never recorded.<\/p><\/dd>\n<dt id=\"does%20goal%20and%20scroll%20tracking%20add%20requests%3F\"><h3>Does goal and scroll tracking add requests?<\/h3><\/dt>\n<dd><p>No. Goals and scroll depth are sent together with the regular engagement pings, so the number of requests per pageview stays the same.<\/p><\/dd>\n<dt id=\"who%20can%20see%20the%20statistics%3F\"><h3>Who can see the statistics?<\/h3><\/dt>\n<dd><p>Users with the <code>manage_options<\/code> capability (administrators). Developers can change it with the <code>visitrix_view_capability<\/code> filter.<\/p><\/dd>\n<dt id=\"will%20deleting%20the%20plugin%20delete%20my%20statistics%3F\"><h3>Will deleting the plugin delete my statistics?<\/h3><\/dt>\n<dd><p>Only if you enable \"Delete all statistics and settings when the plugin is deleted\" in the settings. By default the data is kept.<\/p><\/dd>\n<dt id=\"how%20do%20i%20store%20the%20statistics%20in%20a%20separate%20database%3F\"><h3>How do I store the statistics in a separate database?<\/h3><\/dt>\n<dd><p>Create a MySQL or MariaDB database and a user with the right to create tables in it (at your hosting or a cloud provider). Then open Statistics \u2192 Settings \u2192 Data storage, choose \"A separate MySQL \/ MariaDB database\", enter the host, port, database name, user and password, click \"Check connection\" and save. For cloud databases enable SSL\/TLS and paste the CA certificate your provider gives you. Finally click \"Copy earlier statistics\" and, after it finishes, \"Delete them from the WordPress database\" to free the space.<\/p><\/dd>\n<dt id=\"can%20i%20keep%20the%20database%20password%20out%20of%20the%20admin%3F\"><h3>Can I keep the database password out of the admin?<\/h3><\/dt>\n<dd><p>Yes. Add the connection to wp-config.php, and the settings screen becomes read-only:<\/p>\n\n<pre><code>define( 'VISITRIX_DB_HOST', 'db.example.com:3306' );\ndefine( 'VISITRIX_DB_NAME', 'stats' );\ndefine( 'VISITRIX_DB_USER', 'stats_user' );\ndefine( 'VISITRIX_DB_PASSWORD', 'secret' );\ndefine( 'VISITRIX_DB_PREFIX', 'wp_' ); \/\/ optional\ndefine( 'VISITRIX_DB_SSL', true ); \/\/ optional\ndefine( 'VISITRIX_DB_SSL_CA', '\/path\/to\/ca.pem' ); \/\/ optional\n<\/code><\/pre>\n\n<p>A password entered in the admin is stored encrypted with the keys of wp-config.php.<\/p><\/dd>\n<dt id=\"does%20a%20remote%20database%20slow%20the%20site%20down%3F\"><h3>Does a remote database slow the site down?<\/h3><\/dt>\n<dd><p>Only the beacon requests talk to it, not the pages your visitors see. Choose a database in the same region as your hosting. If the database stops answering, Visitrix pauses new connection attempts for a minute so beacons stay fast.<\/p><\/dd>\n<dt id=\"how%20do%20i%20connect%20clickhouse%3F\"><h3>How do I connect ClickHouse?<\/h3><\/dt>\n<dd><p>Create a service (for example in ClickHouse Cloud or Yandex Cloud), then open Statistics \u2192 Settings \u2192 Data storage, choose \"ClickHouse\", enter the HTTPS address (e.g. <code>https:\/\/abc123.eu-central-1.aws.clickhouse.cloud:8443<\/code>), the database (usually <code>default<\/code>), the user and the password, click \"Check connection\" and save. ClickHouse 23.3 or newer is required. In wp-config.php the same is done by setting <code>VISITRIX_DB_HOST<\/code> to the HTTPS address.<\/p><\/dd>\n<dt id=\"is%20clickhouse%20faster%20than%20mysql%20for%20visitrix%3F\"><h3>Is ClickHouse faster than MySQL for Visitrix?<\/h3><\/dt>\n<dd><p>For large sites with millions of visits it keeps the reports fast and takes much less space thanks to compression. For a small site the WordPress database is perfectly fine. Reports are built from views over the event log, so a ClickHouse server in the same region as your hosting gives the best response time.<\/p><\/dd>\n<dt id=\"where%20can%20i%20get%20support%3F\"><h3>Where can I get support?<\/h3><\/dt>\n<dd><p>Use the support forum on WordPress.org or write to the developer in Telegram: <a href=\"https:\/\/t.me\/Alex_mlr_dev\">t.me\/Alex_mlr_dev<\/a>.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>New: ClickHouse storage \u2013 ClickHouse Cloud, Yandex Cloud, Altinity or your own server, over HTTP(S), no PHP extension needed. Events are written append-only; views assemble visits, pages and goals with the same rules as MySQL, so all reports work unchanged. Retention by TTL.<\/li>\n<li>New: copy earlier statistics from the WordPress database to ClickHouse in one click.<\/li>\n<li>External databases: one kept-alive connection per request and retries on dropped connections.<\/li>\n<li>Fix: the database fields of the storage settings now follow the choice restored by the browser after a reload.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: optional separate database for the statistics \u2013 a second MySQL\/MariaDB database of your hosting or a cloud one (Yandex Cloud, VK Cloud, Selectel, Timeweb Cloud, Amazon RDS, Google Cloud SQL, Azure, DigitalOcean, PlanetScale, TiDB Cloud and other MySQL-compatible services). By default nothing changes: the statistics stay in the WordPress database.<\/li>\n<li>New: connection check, SSL\/TLS with a CA certificate, settings in wp-config.php constants, encrypted password.<\/li>\n<li>New: copy earlier statistics to the new database and empty the WordPress tables in one click.<\/li>\n<li>Reports are refreshed right after the storage or the data changes.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>New: a \u201cDonate\u201d button on the plugin pages and a Donate link on the Plugins screen.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: goals without setup \u2013 forms, phone calls, e-mails, messengers, downloads and outbound links, with conversion by source.<\/li>\n<li>New: scroll map on top of the page for PC, smartphones and tablets.<\/li>\n<li>New: read depth for pages and posts.<\/li>\n<li>New: content report \u2013 posts, categories, tags and authors.<\/li>\n<li>Goals and scroll depth are sent with existing pings: no extra requests.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Performance: a lightweight collector replaces the REST API endpoint for tracker beacons.<\/li>\n<li>Performance: fewer engagement pings; the first interaction is sent together with the next ping.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: accurate new vs returning visitors \u2013 every visitor belongs to exactly one group, decided on the server.<\/li>\n<li>New: \"Accurate\" identification mode with a first-party cookie (works in Safari and across www\/non-www).<\/li>\n<li>New: \"Anonymous\" mode without any browser storage.<\/li>\n<li>New: WP Consent API support.<\/li>\n<li>New: robot filter \u2013 visits are counted after the first real interaction.<\/li>\n<li>New: \"Online now\" and the loyalty report.<\/li>\n<li>New: \"Do not count this browser\" button in the settings.<\/li>\n<li>Fix: pages prerendered by the browser but never opened are no longer counted.<\/li>\n<li>Fix: when localStorage is blocked, the tracker falls back to sessionStorage instead of creating a new visitor on every page.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Translations are now loaded from translate.wordpress.org.<\/li>\n<li>The admin menu item is placed after the core menu items.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: \"New and returning visitors\" report.<\/li>\n<li>New: \"New visitors\" line on the traffic chart.<\/li>\n<li>New: support link on the Plugins screen.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Lightweight self-hosted visitor statistics: traffic sources, search engines, devices, browsers, time on site and bounce rate. No external services.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/388209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=388209"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/akklex"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=388209"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=388209"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=388209"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=388209"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=388209"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=388209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}