Configuration
Everything here has a working default. A fresh install needs none of it.
Settings live at Settings → Plugins → Odometer, and in project config like any other plugin's.
Counting
How views are counted
| Automatically (default) | Counted while Craft renders the page. Two statements, no reads. |
| With a beacon | The page carries a signed token; the browser fetches one tiny URL. |
| Only where asked | Nothing is counted except where a template or some PHP says so. |
| Not at all | Nothing is counted. Everything already counted is left alone. |
Automatic is right for most sites and wrong for exactly one kind: a site behind a full-page cache, where Craft renders once and every reader after the first is invisible.
Beacon type
An image is a 1×1 GIF. It counts readers with JavaScript switched off, and it is served from your own domain rather than an analytics host, so most blockers leave it alone.
A script does not count a page the browser merely prefetched, preloaded or prerendered but
nobody looked at — which an image cannot tell apart from a reader. It carries its URL in a data
attribute rather than inline code, so it needs no unsafe-inline in a content security policy.
Token lifetime
Minutes a beacon token stays valid. The default, 0, means it never expires, and that is deliberate: in beacon mode the token lives inside the page's HTML, and on a cached site that HTML may be served for weeks. An expiring token there is a counter that quietly stops working, days after anybody was watching.
The token permits exactly one thing — adding to one element's count — and every other rule (robots, addresses, repeat visits) still applies to the request carrying it.
Repeat views
How many minutes before the same visitor reading the same page counts again. Default 30.
0 counts every single request, refreshes included, which is occasionally what you want (a
downloads counter) and usually not (an article).
The test hashes the address and user agent with the site's security key and keeps the hash in Craft's cache for exactly that long. Nothing is written to the database and there is no cookie.
What gets counted
Sections — every one, only a list, or every one except a list.
Other element types — categories, products, and anything else with a URL. Sections say nothing about these, so they get their own switch rather than an accidental answer.
Drafts, revisions, previews and control-panel requests are never counted, and there is no setting for that.
Who gets counted
Ignore robots (on) with a list of about sixty user-agent fragments, matched case-insensitively anywhere in the string. A user agent is a claim rather than a fact, so this removes most of the noise and cannot remove all of it. Add your own; an empty user agent is always treated as a robot, because every browser sends one.
Ignored addresses — exact addresses (203.0.113.7), dotted prefixes (198.51.100.) or CIDR
ranges (203.0.113.0/24, 2001:db8::/32). The office, the uptime monitor, the staging box.
Signed-in users — count everybody, ignore admins (default), or ignore every signed-in user.
Anything other than "count everybody" means asking Craft who the visitor is, and that opens a session — which means a
Set-Cookieon the response, which means a full-page cache that never stores the page again. Odometer only asks once it can already see a session cookie on the request, so an anonymous reader never pays for this setting. If you run a page cache and want to be certain nothing ever touches the session, set this to Count everybody.
Honour Do Not Track (on) — skips DNT: 1 and Sec-GPC: 1. Odometer stores nothing about anybody
either way, so this is a courtesy rather than a compliance control.
History
Keep day-by-day history for — 730 days by default. 0 keeps it forever.
Retention prunes day buckets and never touches lifetime totals. Turning retention down costs you the ability to ask about a window that far back; it never costs anyone their view count.
Pruning runs with Craft's own garbage collection, and on demand from the report screen or
php craft odometer/views/prune.
Trending window (7 days) and trending half-life (3 days) — how far back trending looks, and
how quickly a view stops mattering. A half-life of 3 means a view from six days ago counts a quarter
as much as one from today. 0 turns decay off, which makes trending "most views in the window" — a
fine answer, and a slower-moving one.
Control panel
Show a panel in the entry sidebar (on) — the lifetime number, the last seven days, thirty days of history, and a link to the full history. No field layout to edit.
Offer a Views column on element indexes (on) — a sortable Views column wherever elements can have URLs. Editors still have to add it to a source's columns; this only puts it on the menu.
Counters
Default counter — leave empty unless you know you want more than one counter per element. Changing it orphans every count already recorded under the old name.
To use several, pass a key to any method:
{% do craft.odometer.record(entry, { key: 'downloads' }) %}
{{ craft.odometer.views(entry, 'all', { key: 'downloads' }) }}
Permissions
- View reports — the Odometer section, the sidebar panel, the widget, the field.
- Reset and prune view counts (nested) — the buttons that delete things.