{"id":339868,"date":"2026-07-17T03:17:48","date_gmt":"2026-07-17T03:17:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/sawir-insights\/"},"modified":"2026-07-17T03:31:53","modified_gmt":"2026-07-17T03:31:53","slug":"sawir-insights","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/sawir-insights\/","author":18200539,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.0.1","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Sawir Insights","header_author":"Ricardo Sawir, Sawir Studio LLC","header_description":"Self-hosted heatmaps, session recordings, surveys and funnels. Your visitor data never leaves your server.","assets_banners_color":"","last_updated":"2026-07-17 03:31:53","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/sawir-insights\/","header_author_uri":"https:\/\/sawirstudio.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":35,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sawirricardo","date":"2026-07-17 03:31:53"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[232,6207,396,125244,364],"plugin_category":[36,42,54],"plugin_contributors":[262686],"plugin_business_model":[],"class_list":["post-339868","plugin","type-plugin","status-publish","hentry","plugin_tags-analytics","plugin_tags-heatmap","plugin_tags-privacy","plugin_tags-session-recording","plugin_tags-survey","plugin_category-analytics","plugin_category-contact-forms","plugin_category-security-and-spam-protection","plugin_contributors-sawirricardo","plugin_committers-sawirricardo"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/sawir-insights.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Sawir Insights is behavioral analytics for WordPress: heatmaps, session recordings, surveys, a feedback widget, form analytics, conversion funnels, and a dashboard that ties them together.<\/p>\n\n<p>On multisite networks, each site tracks and configures its analytics independently.<\/p>\n\n<p>The reason it exists is simple. The established tools in this category are good, but they work by shipping a record of everything your visitors do to someone else's servers. For a lot of sites \u2014 especially in the EU \u2014 that is somewhere between uncomfortable and unworkable. I wanted the same class of tooling where the data never leaves the site that collected it. So that is the constraint this plugin is built around: your database, your uploads directory, your retention rules. There is no SaaS behind it, no account to create, and no phone-home of any kind.<\/p>\n\n<p><strong>What it does<\/strong><\/p>\n\n<ul>\n<li>Click, movement, and scroll heatmaps, rendered over your live pages, split by desktop, tablet, and mobile.<\/li>\n<li>Session recordings with playback in wp-admin. Input values are always masked; recording is off until you turn it on.<\/li>\n<li>Popup surveys and a persistent feedback tab, with targeting by URL, device, traffic percentage, time on page, scroll depth, or exit intent.<\/li>\n<li>Form analytics: where people hesitate, what they leave empty, where they abandon. Selectors and timing only \u2014 never what anyone typed.<\/li>\n<li>Ordered conversion funnels with daily reports.<\/li>\n<li>A dashboard with traffic KPIs and period deltas, a daily trend chart, and device, browser, page, referrer, campaign, funnel, and recording breakdowns.<\/li>\n<\/ul>\n\n<p><strong>What it deliberately does not do<\/strong><\/p>\n\n<p>I think you should know what a tool refuses to do before you install it.<\/p>\n\n<ul>\n<li>It does not store IP addresses. Not hashed, not truncated \u2014 at all.<\/li>\n<li>It does not record form values, ever. The capture layer sends metadata only, so there is nothing to leak.<\/li>\n<li>It does not load anything from a CDN or send anything to one. The rrweb replay library ships inside the plugin.<\/li>\n<li>It does not keep raw data forever. Events are aggregated and pruned on a retention schedule you control, and recordings have their own retention and a disk cap with oldest-first eviction, because a plugin that quietly fills your hosting disk is a bad plugin.<\/li>\n<\/ul>\n\n<p>The frontend tracker is small vanilla JavaScript, batched over <code>sendBeacon<\/code>, with sampling controls. Visitors who are not sampled into recording never download the replay library at all.<\/p>\n\n<p><strong>Privacy posture<\/strong><\/p>\n\n<p>Do Not Track is honored by default. A consent-mode API (<code>window.swinsConsent<\/code>) integrates with whatever consent manager you already run. Sessions, events, and recordings are wired into WordPress's own personal-data export and erasure tools. Whether your specific deployment is GDPR compliant depends on your notices and legal basis \u2014 that part no plugin can do for you \u2014 but the data-minimization work is done.<\/p>\n\n<p><strong>Support<\/strong><\/p>\n\n<p>Support runs through the wordpress.org forum for this plugin, or email ricardo@sawirstudio.com.<\/p>\n\n<h3>Other plugins by Sawir Studio<\/h3>\n\n<p>If Sawir Insights fits how you like tools to work, I make a few others in the same spirit:<\/p>\n\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-live-translate\/\">Sawir Live Translate<\/a> \u2014 translate any front-end page live and let visitors switch languages.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-restock-notifier-for-woocommerce\/\">Sawir Restock Notifier for WooCommerce<\/a> \u2014 let customers request an email when an out-of-stock product is back.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-product-image-zoom-for-woocommerce\/\">Sawir Product Image Zoom for WooCommerce<\/a> \u2014 product image lightbox with navigation and click-to-zoom.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-min-max-quantities-for-woocommerce\/\">Sawir Min Max Quantities for WooCommerce<\/a> \u2014 minimum, maximum, and group-of order quantity rules.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-variation-gallery-tools-woocommerce\/\">Sawir Variation Gallery Tools for WooCommerce<\/a> \u2014 manage variation-specific gallery images.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-role-capabilities-manager\/\">Sawir Role Capabilities Manager<\/a> \u2014 create custom user roles and manage capabilities.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-media-folders\/\">Sawir Media Folders<\/a> \u2014 organize the Media Library into fast, unlimited folders with drag &amp; drop.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>sawir-insights<\/code> directory to <code>\/wp-content\/plugins\/<\/code>, or install through the Plugins screen.<\/li>\n<li>Activate Sawir Insights.<\/li>\n<li>Open Insights \u2192 Settings and review the privacy and sampling options. Tracking is on after activation; session recording is not.<\/li>\n<li>Give it some traffic, then open Insights \u2192 Dashboard.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20sawir%20insights%20gdpr%20compliant%3F\"><h3>Is Sawir Insights GDPR compliant?<\/h3><\/dt>\n<dd><p>The plugin is built for privacy-conscious deployments: data stays on your server, IP addresses are never stored, retention is configurable, Do Not Track is honored, and WordPress export\/erasure tools are integrated. Compliance itself depends on your configuration, notices, legal basis, and consent implementation \u2014 consult qualified counsel for your site.<\/p><\/dd>\n<dt id=\"does%20visitor%20data%20leave%20my%20server%3F\"><h3>Does visitor data leave my server?<\/h3><\/dt>\n<dd><p>No. The plugin sends no behavioral data to Sawir Studio or any analytics provider. Events live in your WordPress database; recording files live beneath your protected uploads directory.<\/p><\/dd>\n<dt id=\"can%20analytics%20data%20live%20in%20its%20own%20database%3F\"><h3>Can analytics data live in its own database?<\/h3><\/dt>\n<dd><p>Yes. I keep this as a wp-config.php-only setting so database credentials never enter the WordPress options table. Define all four constants before the \"That's all, stop editing\" line:<\/p>\n\n<pre><code>define( 'SWINS_DB_HOST', 'localhost' );\ndefine( 'SWINS_DB_NAME', 'analytics' );\ndefine( 'SWINS_DB_USER', 'analytics_user' );\ndefine( 'SWINS_DB_PASSWORD', 'a-strong-password' );\n<\/code><\/pre>\n\n<p>The analytics tables keep the main site's table prefix, so moving between the WordPress database and an external database is a plain table copy. Do not run two live collecting databases for one site: copy the tables, switch the constants, and only then resume collection. Otherwise you will split one site's history across two databases.<\/p><\/dd>\n<dt id=\"does%20it%20store%20ip%20addresses%3F\"><h3>Does it store IP addresses?<\/h3><\/dt>\n<dd><p>No.<\/p><\/dd>\n<dt id=\"how%20do%20i%20connect%20a%20consent%20manager%3F\"><h3>How do I connect a consent manager?<\/h3><\/dt>\n<dd><p>Enable \"Require consent before tracking,\" then call <code>window.swinsConsent('grant')<\/code> when consent is granted and <code>window.swinsConsent('revoke')<\/code> when it is withdrawn. The decision is saved in a first-party cookie.<\/p><\/dd>\n<dt id=\"are%20form%20values%20captured%3F\"><h3>Are form values captured?<\/h3><\/dt>\n<dd><p>No. Form capture records selectors, timing, and empty-state metadata only. Values never leave the browser.<\/p><\/dd>\n<dt id=\"how%20are%20session%20recordings%20protected%3F\"><h3>How are session recordings protected?<\/h3><\/dt>\n<dd><p>Recording is disabled by default. When enabled, all input values are masked automatically, canvas capture is off, and replay chunks stay beneath the guarded <code>wp-content\/uploads\/sawir-insights\/recordings\/<\/code> directory. Only administrators can retrieve them, through an authenticated REST endpoint.<\/p><\/dd>\n<dt id=\"how%20do%20i%20mask%20or%20block%20sensitive%20page%20areas%3F\"><h3>How do I mask or block sensitive page areas?<\/h3><\/dt>\n<dd><p>Add the <code>swins-mask<\/code> class or <code>data-swins-mask<\/code> attribute to mask an element's text. Add the <code>swins-block<\/code> class to omit an element entirely from recordings.<\/p><\/dd>\n<dt id=\"how%20is%20recording%20disk%20usage%20controlled%3F\"><h3>How is recording disk usage controlled?<\/h3><\/dt>\n<dd><p>Insights \u2192 Settings has separate recording retention and disk-cap controls. Past the cap, the oldest recordings are removed first. Usage is tracked continuously and recalculated weekly.<\/p><\/dd>\n<dt id=\"how%20do%20surveys%20decide%20when%20to%20appear%3F\"><h3>How do surveys decide when to appear?<\/h3><\/dt>\n<dd><p>Each active survey can target URL patterns, devices, a stable percentage of sessions, time on page, scroll depth, or desktop exit intent. One survey per browser session; dismissed surveys stay hidden for 30 days.<\/p><\/dd>\n<dt id=\"how%20complete%20are%20funnel%20reports%3F\"><h3>How complete are funnel reports?<\/h3><\/dt>\n<dd><p>Funnels are computed from ordered page-view and click metadata retained on your server, so history is bounded by the raw-event retention window in Insights \u2192 Settings.<\/p><\/dd>\n<dt id=\"why%20do%20heatmaps%20lag%20behind%20live%20traffic%3F\"><h3>Why do heatmaps lag behind live traffic?<\/h3><\/dt>\n<dd><p>I fold raw events into heatmap aggregates hourly through WP-Cron. WordPress only runs WP-Cron when someone visits the site, so on a low-traffic site I recommend a real system cron, for example: <code>*\/5 * * * * cd \/path\/to\/wordpress &amp;&amp; wp cron event run --due-now<\/code><\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Added the self-hosted analytics foundation.<\/li>\n<li>Added optional wp-config.php constants for keeping analytics tables in a dedicated database.<\/li>\n<li>Added click, movement and scroll collection and heatmap aggregation.<\/li>\n<li>Added live-page heatmap administration.<\/li>\n<li>Added privacy controls, consent API, exporter and eraser.<\/li>\n<li>Added sampled session recording capture, protected chunk storage, retention, disk-cap eviction, recording administration, and rrweb playback.<\/li>\n<li>Vendored rrweb 2.1.0 and rrweb-player 2.1.0 browser bundles locally.<\/li>\n<li>Added targeted popup surveys and an accessible persistent feedback widget.<\/li>\n<li>Added survey administration, per-question results, NPS scoring, and CSV export.<\/li>\n<li>Added privacy-safe daily form analytics with field timing, abandonment, and completion reporting.<\/li>\n<li>Added ordered page-view and click funnels with retention-aware daily conversion reports.<\/li>\n<li>Added the analytics dashboard with KPI deltas, an inline daily trend chart, device, browser, OS, page, referrer, and UTM breakdowns, funnel and recording summaries, and date, device, and UTM source filters.<\/li>\n<\/ul>","raw_excerpt":"Heatmaps, session recordings, surveys, funnels, and form analytics. Everything stays on your server.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/339868","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=339868"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sawirricardo"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=339868"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=339868"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=339868"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=339868"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=339868"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=339868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}