Title: AnGo Scroll Analytics
Author: andrewgolubev
Published: <strong>20. september 2026</strong>
Last modified: 21. september 2026

---

Søk gjennom innstikk

![](https://ps.w.org/ango-scroll-analytics/assets/icon.svg?rev=3704194)

# AnGo Scroll Analytics

 Av [andrewgolubev](https://profiles.wordpress.org/andrewgolubev/)

[Last ned](https://downloads.wordpress.org/plugin/ango-scroll-analytics.1.3.0.zip)

 * [Detaljar](https://nn.wordpress.org/plugins/ango-scroll-analytics/#description)
 * [Omtalar](https://nn.wordpress.org/plugins/ango-scroll-analytics/#reviews)
 *  [Installasjon](https://nn.wordpress.org/plugins/ango-scroll-analytics/#installation)
 * [Utvikling](https://nn.wordpress.org/plugins/ango-scroll-analytics/#developers)

 [Hjelp](https://wordpress.org/support/plugin/ango-scroll-analytics/)

## Skildring

AnGo Scroll Analytics records how far visitors scroll through your posts and pages
and shows the result on a «Readability» screen in wp-admin. It answers the question
a pageview count cannot: did anyone actually read past the first screen?

The tracking script is loaded only on single posts and pages (is_singular for the
post and page types) and measures how far the page was scrolled during a visit. 
That is depth through the scrollable height of the document, not the share of the
article visible on screen: a page that fits on one screen records 100%.

A visit is registered as soon as the page loads — a visitor who scrolls nowhere 
still gets a row, with 0%. After that, data is sent to the server only when reading
progress actually advances (checked every 5 seconds), and always when the visitor
leaves the page or switches tabs (via navigator.sendBeacon, or fetch with keepalive
where it is unavailable). A failed send is retried at the next check.

One visit is one row in the table, updated as the reader gets further down. A new
tab or a new session is a new visit.

#### What the dashboard shows

 * The period, chosen by hand (the last 30 days by default), with an «Apply» button
   and grouping by day or by month.
 * A summary for the selected period: number of visits, average scroll %, median.
 * Percentiles 50/75/90/100, phrased as «X% of visitors scrolled at least to Y% 
   of the article».
 * An «Exclude load-and-die visits» checkbox (on by default): visits whose only 
   beacon fired at page load — on a live site mostly bots and link previews — are
   left out of the statistics, and the Visits card shows how many were excluded.
   Uncheck it to see the raw population.
 * A trend chart: average scroll as a line, visits as bars.
 * A table per item: title, type (post/page), visits, average scroll, median, 90th
   percentile, sorted by visit count.

#### Performance at scale

The plugin computes the statistics on the fly with database queries. At very large
volumes (hundreds of thousands of visits) caching (transients) or cron-based aggregation
is worth adding. A typical blog does not need it.

#### Rate limiting and the database

Without a persistent object cache, each beacon writes the throttle counter to the
options table, so the limit costs two queries per beacon. That is cheap at the scale
this plugin targets — it is a spam brake, not a firewall.

## Installasjon

 1. In wp-admin go to Plugins  Add New  Upload Plugin.
 2. Choose the downloaded archive (ango-scroll-analytics-1.3.0.zip), click «Install
    Now», then «Activate».
 3. On activation the plugin creates its table in the database, {prefix}_ango_visits(
    wp_ango_visits with the default prefix). If the schema changes in a later version,
    the table is brought up to date the next time wp-admin is opened (dbDelta).
 4. A «Readability» entry appears in the left-hand menu — the dashboard lives there.

## Vanlege spm.

### Do visits with no scrolling really count?

Yes. Every arrival is a row, including the ones with 0% scroll: the percentiles 
describe all arrivals, not only those who read to the end. That is a deliberate 
decision, not lost data.

The dashboard does distinguish two kinds of zero-scroll visits. A visit that sent
nothing after the initial page-load beacon (max_scroll 0 and time on page 0) is «
load-and-die» — on a live site those are usually bots, crawlers and link previews,
not people. They are excluded from the statistics by default (the Visits card shows
how many were left out), while a person who loaded the page and stayed without scrolling—
time on page above zero — always counts. The checkbox in the filter bar turns the
exclusion off.

### Is the tracking endpoint public?

Yes — it has to be, because visitors are not logged in. POST /wp-json/ango/v1/depth
is limited to 60 requests per minute per IP; the limit is changed through the ango_rate_limit
filter, and a value below 1 disables the check. The IP itself is not stored, only
a hash of it, for the duration of the window. Behind a proxy (Cloudflare and similar)
REMOTE_ADDR is the proxy address, so the limit is shared by all visitors — raise
it in that setup.

### Why do the numbers differ from my analytics tool?

This plugin measures depth through the scrollable height of the page, not the share
of the article that was on screen: a short page that fits on one screen records 
100%. And it counts visits, not unique readers — a new tab or a new session is a
new visit.

### What timezone are the numbers in?

Timestamps in the table (created_at) are stored in UTC, while the dashboard computes
day boundaries in the site timezone. Keep that in mind when writing manual SQL against{
prefix}_ango_visits.

### Can I track custom post types?

The tracking script is loaded only on single posts and pages (is_singular( [ «post»,«
page» ] )). To track custom post types as well, add them to that list in ango-scroll-
analytics.php, in ango_enqueue_tracker().

### Does the admin screen load anything from outside my site?

No. The chart is drawn by Chart.js 4.5.1, bundled with the plugin (assets/vendor/
chart.umd.min.js, MIT license), so wp-admin makes no external request and the chart
works offline and behind a filtering proxy.

### Why does the bundled Chart.js ship minified?

Chart.js 4.5.1 (MIT) ships here as the minified UMD build that upstream publishes—
assets/vendor/chart.umd.min.js, licence banner intact. Upstream has no unminified
UMD to use instead: dist/chart.umd.js and dist/chart.umd.min.js in its package are
both minified. The readable code is published, just in another build: the unminified
ESM bundle is dist/chart.js (https://unpkg.com/chart.js@4.5.1/dist/chart.js), and
the sources it is built from are at https://github.com/chartjs/Chart.js/tree/v4.5.1/
src.

### Why are the file names so plain?

They are deliberately neutral: the tracking script is assets/js/scroll-depth.js 
and the public endpoint is /wp-json/ango/v1/depth, with no tracker/track in either.
Those words are a common target for filter lists, and a blocked script or beacon
loses data silently. Neither EasyList/EasyPrivacy nor the uBlock Origin and AdGuard
filters matched these URLs (checked 2026-09-16 under the plugin’s previous name;
the endpoint paths did not change in the rename), but the lists update daily — so
do not rename them back «for clarity».

### How do I update the Russian translation?

English is the source language; Russian is a translation (languages/ango-scroll-
analytics-ru_RU.po). For the WordPress.org-hosted plugin the catalogue is served
by translate.wordpress.org and no translation files ship in the package — the .po
lives in the development repository for contributors. A site that installs the plugin
from the WordPress.org directory receives community translations automatically; 
WordPress reads the compiled .mo, so after editing the .po you must rebuild it:

msgfmt -o languages/ango-scroll-analytics-ru_RU.mo languages/ango-scroll-analytics-
ru_RU.po

If gettext is not installed, a minimal Python MO writer does the same job. The test
suite checks that the .po and the .mo stay in agreement: python3 tests/run.py

### What happens to my data when I uninstall the plugin?

Deleting the plugin removes everything it stored: the {prefix}_ango_visits table,
the ango_db_version option and the throttle transients. Deactivating does not — 
the data survives a deactivate and reactivate cycle, so an upgrade or a temporary
switch-off costs nothing. Clicking Delete on the Plugins screen shows a confirmation
naming the statistics that will be lost. If you need the numbers after the plugin
is gone, export them before deleting, or hold the cleanup back from a must-use plugin
with add_filter( «ango_remove_data_on_uninstall», «__return_false» ).

## Omtalar

There are no reviews for this plugin.

## Bidragsytarar og utviklarar

“AnGo Scroll Analytics” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ andrewgolubev ](https://profiles.wordpress.org/andrewgolubev/)

[Omset “AnGo Scroll Analytics” til ditt eige språk.](https://translate.wordpress.org/projects/wp-plugins/ango-scroll-analytics)

### Interested in development?

[Les kjeldekoden](https://plugins.trac.wordpress.org/browser/ango-scroll-analytics/),
sjekk [SVN-lageret](https://plugins.svn.wordpress.org/ango-scroll-analytics/) eller
abonner på [utviklingsloggen](https://plugins.trac.wordpress.org/log/ango-scroll-analytics/)
med [RSS](https://plugins.trac.wordpress.org/log/ango-scroll-analytics/?limit=100&mode=stop_on_copy&format=rss).

## Om

 *  Version **1.3.0**
 *  Last updated **11 minutt sidan**
 *  Active installations **Færre enn 10**
 *  WordPress version ** 6.8 eller nyare **
 *  Tested up to **7.1.1**
 *  PHP version ** 7.4 eller nyare **
 *  Language
 * [English (US)](https://wordpress.org/plugins/ango-scroll-analytics/)
 * Tags
 * [content](https://nn.wordpress.org/plugins/tags/content/)[engagement](https://nn.wordpress.org/plugins/tags/engagement/)
   [scroll depth](https://nn.wordpress.org/plugins/tags/scroll-depth/)[statistics](https://nn.wordpress.org/plugins/tags/statistics/)
 *  [Avansert vising](https://nn.wordpress.org/plugins/ango-scroll-analytics/advanced/)

## Vurderingar

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/ango-scroll-analytics/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/ango-scroll-analytics/reviews/)

## Contributors

 *   [ andrewgolubev ](https://profiles.wordpress.org/andrewgolubev/)

## Hjelp

Har du noko å seia? Treng du hjelp?

 [Sjå hjelpeforumet](https://wordpress.org/support/plugin/ango-scroll-analytics/)