BLACK FRIDAY
Save 59% on PageForge Annual $191/year $485/year
Claim 59% Off →
WP-PostViews icon
Actively maintained Tested with WP 7.1 #462 most installed plugin #2 in Counter

WP-PostViews

Enables you to display how many times a post/page had been viewed.

Active installs100K+100K+ tier
Downloads · 30d11.5K▼ -73.6% vs prev. 30d
Rating4.4/565 reviews
Health score85/100Excellent
All-time downloads3.5MSince Feb 2006
Support resolved—No recent threads
RequiresWP 6.8PHP 8.2+
Overall rank#462of 69,606 plugins
Our verdict

Safe pick

Yes — WP-PostViews is a safe, well-maintained plugin to use in 2026. It runs on 100K+ sites, is rated 4.4/5 and was last updated 1 month ago, and scores 85/100 on our health check.

  • Proven at scale on 100K+ active sites
  • Tested with the latest WordPress (7.1)
  • Needs PHP 8.2 or newer

How does it stack up?

Side-by-side on installs, updates, ratings & support

Daily downloads

4.7K9.4K14.1KJun 30Aug 13Sep 27
Yesterday219
Daily average (1y)413
Peak day18,791Jul 25, 2026
Last 12 months150.4K

Download spikes usually follow a new release — each site that auto-updates counts as a download.

Rankings

Where WP-PostViews stands today
Overall popularity #462 of 69,606 WordPress.org plugins Top 0.66%
100K+ installs tier 330 of 334
Next tier: 500K+ installs
Counter #2 of 133 plugins → Hits #1 of 21 plugins → Postviews #2 of 16 plugins → Statistics #6 of 289 plugins → Views #1 of 47 plugins →

WordPress.org search rankings

Live position in the plugin search, top 100
KeywordPositionCompeting pluginsCategory
Counter #35 2,716 Best Counter plugins →
hits #5 2,564 Best hits plugins →
postviews #1 44 Best postviews plugins →
statistics #29 3,103 Best statistics plugins →
views #34 10,000 Best views plugins →

Version adoption

Share of active sites per release.

  • 1.7832.4%
  • 2.021.5%
  • 1.7721.1%
  • 1.7617.4%
  • Other7.6%

Rating breakdown

★★★★★★★★★★ 4.4 from 65 reviews

  • 5★73.8%
  • 4★12.3%
  • 3★1.5%
  • 2★1.5%
  • 1★10.8%

About WP-PostViews

From the official readme · v2.0.1

Description

WP-PostViews counts how many times each post, page or custom post type has been read and gives you somewhere to show the number. The count is kept as post meta, so it sorts, queries and exports like anything else WordPress stores about a post.

Features

  • A view count on any post, page or custom post type, printed by a template tag or by the [views] shortcode.
  • Two templates you edit yourself, with tokens for the count, the title, the date, the excerpt, the thumbnail, the author and more.
  • Choose who is counted — everyone, guests only or logged in users only — and leave known robots out.
  • Template tags and a widget for the most and least viewed posts, optionally within a category or a tag.
  • A sortable Views column on the post and page list tables.
  • The count on the REST API as a views field, and an AJAX counting path for sites behind a page cache.
  • A section on the WP-Stats page when that plugin is installed.

Donations

I spent most of my free time creating, updating, maintaining and supporting these plugins, if you really love my plugins and could spare me a couple of bucks, I will really appreciate it. If not feel free to use it without any obligations.

Usage

The simplest way, and the only one that works in a block theme without editing template files, is the shortcode. Put it in the post or page whose count you want shown:

  • [views] shows the count for the post it appears in.
  • [views id="1"] shows the count for post 1, wherever you put it.

To show the count on every post automatically, a classic theme calls the template tag from index.php, archive.php, single.php or page.php, anywhere inside the loop:

<?php if ( function_exists( 'the_views' ) ) { the_views(); } ?>

The settings live at WP-Admin -> Settings -> WP-PostViews, on two tabs. Settings is where you choose who gets counted and whether WP-Stats is offered a Views section; Templates is where you edit the markup a count is rendered with.

Where the count appears is decided by where your theme calls the_views() or where you put the shortcode. To hide it somewhere in particular, answer the wp_postviews_should_display filter:

add_filter( 'wp_postviews_should_display', function ( $show ) {
    return ! is_archive() && ! is_search();
} );

Showing The View Count In A Block

One block is available in the editor, under Widgets:

  • Post Views — the view count, rendered with the template from the Templates tab. Leave Post ID at zero to show the count of the post the block is in, which is what an empty [views] does, or set it to another post’s ID to show that post’s count instead.

It renders on the server, so the block preview in the editor is the real number rather than an approximation, and the count keeps rising in every post showing it without anything being re-saved. Previewing the block in the editor does not count a view.

The shortcode still works and is not going anywhere. [views] and [views id="1"] behave exactly as they always have, and a post already containing one needs no change. The block calls the same code the shortcode calls, so the two render identically — use whichever suits the post.

WP-CLI

wp postviews list
wp postviews list --limit=50 --format=json
wp postviews get 42

The command reads and never writes. No screen in this plugin edits a view count, so the command does not offer one either — wp post meta update <id> views <n> is still there for whoever genuinely needs it, and says plainly that it is reaching past the plugin.

REST API

POST /wp-json/postviews/v1/post/<id>/view

Reading a count needs no route of its own. The count is already published as a read-only views field on the core post resource, so /wp-json/wp/v2/posts/<id> answers with the post and its count together, and a list of posts carries every count in one response.

What the core field cannot do is write, which is what this route is for: it counts a view, and it exists for sites serving cached pages, where the view has to be reported after the page is delivered. It takes the same wp_postviews_nonce the counting script is given, as a nonce parameter.

It is refused unless the site defers counting — that is, unless it has a page cache and has turned the AJAX counting path on. Otherwise the view has already been counted while the page rendered, and counting again here would record every view twice.

A refusal answers 403 — a bad nonce, or a site that counts views while the page renders. A post that does not exist is 404.

This route is an addition. The admin-ajax.php wp_postviews action is unchanged and still supported.

Installation

  1. Install and activate the plugin. Counting starts immediately; you do not have to do anything for the numbers to be recorded.
  2. Show the count where you want it: type [views] into a post, add the Post Views block, add the widget, or call the_views() from your theme.
  3. Go to WP-Admin -> Settings -> WP-PostViews to choose who is counted and how the number reads.

Frequently asked questions

How To View Stats With Widgets?

Go to WP-Admin -> Appearance -> Widgets The widget name is Views.

To Display Least Viewed Posts

The first value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The second value you pass in is the maximum number of post you want to get. Default: get_least_viewed(‘both’, 10);

To Display Most Viewed Posts

The first value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The second value you pass in is the maximum number of post you want to get. Default: get_most_viewed(‘both’, 10);

To Display Least Viewed Posts By Tag

The first value you pass in is the tag id. The second value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The third value you pass in is the maximum number of post you want to get. Default: get_least_viewed_tag(1, ‘both’, 10);

To Display Most Viewed Posts By Tag

The first value you pass in is the tag id. The second value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The third value you pass in is the maximum number of post you want to get. Default: get_most_viewed_tag(1, ‘both’, 10);

To Display Least Viewed Posts For A Category

The first value you pass in is the category id. The second value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The third value you pass in is the maximum number of post you want to get. Default: get_least_viewed_category(1, ‘both’, 10);

To Display Most Viewed Posts For A Category

The first value you pass in is the category id. The second value you pass in is the post type that you want. If you want to get every post types, just use ‘both’. It also supports PHP array: example array('post', 'page'). The third value you pass in is the maximum number of post you want to get. Default: get_most_viewed_category(1, ‘both’, 10);

To Sort Most/Least Viewed Posts

You can use: Or pass in the variables to the URL: https://yoursite.com/?v_sortby=views&v_orderby=desc You can replace DESC with ASC if you want the least viewed posts.

To Display Updating View Count With LiteSpeed Cache

Use: to replace . NOTE: The id can be changed, but the div id and the script must match. The plugin’s js/wp-postviews-cache.js already posts the view and receives the new count back, so you only need to write that count into your div. Add this to your theme, or to a small script of your own enqueued after wp-postviews-cache: document.addEventListener( 'postviews:updated', function ( event ) { const target = document.getElementById( 'postviews_lscwp' ); if ( target ) { target.textContent = event.detail.views + ' views'; } } ); Purge the cache to use the updated pages.

To Get Views With REST API

You can obtain the number of post views by adding views to your _fields parameter: /wp/v2/posts?_fields=views,title

Can The Settings Screen Be Handed To Another Role?

The screen requires manage_options. The wp_postviews_capability filter is read wherever that gate is checked, so a different capability opens it to whoever holds one: add_filter( 'wp_postviews_capability', function () { return 'edit_others_posts'; } );

Changelog

Requires WordPress 6.8 and PHP 8.2. View counts, templates and settings all carry over on their own. If your view counts stop appearing, this is why: the_views is now wp_postviews_the_views. That name was far too generic for a filter belonging to one plugin, and it had been public since 1.78.1, so it is very probably sitting in a theme somewhere. Search for the_views: a line like add_filter( 'the_views', … ) needs the new name and nothing else, with identical arguments. A call to the_views() with brackets is the template tag and is unchanged. There is no shim, so the old name fails silently — the symptom is the count appearing but your custom wrapper, prefix or wording gone. Three more were renamed the same way: postviews_should_count is now wp_postviews_should_count, and postviews_increment_views and postviews_increment_views_ajax are now wp_postviews_increment_views and wp_postviews_increment_views_ajax. Update all seven WP-Stats plugins together. WP-PostViews, WP-Stats, WP-Polls, WP-PostRatings, WP-UserOnline, WP-EMail and WP-DownloadManager shared two unprefixed rows; each keeps its own copy now and deletes the shared ones, so whichever you update first takes them from the rest. A missing row means "show", so a section you had hidden may reappear. The views section is toggled on Settings -> WP-PostViews now, which also sets how many entries the most viewed lists carry. WP-Stats receives one Views section rather than three separately switchable panels, so the most viewed pages list appears beside the posts list even if you had only ever asked for posts; untick the whole section if you would rather not see it. The settings screen is options-general.php?page=wp-postviews, not options-general.php?page=wp-postviews/postviews-options.php. The Settings -> WP-PostViews menu item is where it always was. Two rows are renamed on the first load after updating — views_options to wp_postviews_options and views_version to wp_postviews_version — and the old rows are deleted afterwards. Point any code, WP-CLI script or export reading views_options at the new name. Three undocumented functions are gone. should_views_be_displayed(), postviews_round_number() and snippet_text() are now WP_PostViews_Display::should_be_displayed(), ::round_number() and ::snippet_text(). The widget class WP_Widget_PostViews is WP_PostViews_Widget, which matters only if you were instantiating it yourself; widgets already placed in a sidebar are untouched. The Display Options settings are gone, and counts you had hidden will start appearing. The six rows — Home Page, Single Posts, Pages, Archive Pages, Search Pages, Other Pages, each of them "Display to everyone / Display to registered users only / Don't display" — are removed, and the stored display_home, display_single, display_page, display_archive, display_search and display_other keys are dropped on upgrade. If you had set any of them to anything other than "Display to everyone", that choice is not carried over: a site that hid the count on archives or on search results will show it there from the first page load after updating. Restore the gate with the wp_postviews_should_display filter, which is the documented replacement and receives true. Return false to hide the count. All the conditional tags are available, so the old settings map across one for one: add_filter( 'wp_postviews_should_display', function ( $show ) { // "Don't display on archive pages" and "Don't display on search pages". if ( is_archive() || is_search() ) { return false; } // "Display to registered users only", for wherever you had chosen it. if ( is_home() ) { return is_user_logged_in(); } return $show; } ); WP_PostViews_Display::should_be_displayed() is unchanged as a public method and now returns what that filter answers, so anything calling it directly keeps working. The `[views]` shortcode and the admin Views column deliberately do not consult the filter: both are explicit requests for the number. The settings screen is two tabs now, Settings and Templates, at the same URL. The two template fields moved to the Templates tab; everything else stayed. It is still one option row and one Save Changes button per tab, and saving one tab does not disturb the other.

2.0.1

  • NEW: A Settings link on the plugin’s row on the Plugins screen
  • FIXED: “Count Views From” was only honoured while the page rendered. On a cached site the counting happens through a separate AJAX or REST call instead, and that path never asked the setting — so with “Registered Users Only” a guest hitting a cached page was still counted, and the bot exclusion never applied there either. Both endpoints now check the setting against the actual visitor’s login state

2.0.0

  • FIXED: The two templates are echoed as markup on the strength of being wp_kses_post()‘d when saved — and that was true only of the settings screen. The 2.0.0 migration writes through a different door, and the row it folds in comes from a release that stored the field with no filtering at all, so a hostile template on a site upgrading from 1.78.1 was carried across verbatim and echoed to every visitor. The filtering now happens where the row is written, so WP-CLI, cron, a restored backup and another plugin all pass through it too
  • FIXED: The deferred counting endpoint checked only that an ID named something, and every row in wp_posts answers to that — revisions, autosaves, auto-drafts, attachments, trashed posts, drafts, menu items, reusable blocks. An unauthenticated caller could walk the ID space writing a view row against each one, and read back the count of unpublished posts while doing it. It now requires a real, publicly viewable post, which is what the other counting path already knew
  • FIXED: A view count that is not a number — the meta key is unprefixed, so anyone who can edit a post can type one into Custom Fields — turned every listing containing that post into a fatal error on PHP 8, because both count tokens are built whether or not the template uses them
  • NEW: An editor block, Post Views, under Widgets. It renders on the server through the same code the shortcode uses, so a block and a shortcode showing the same post produce the same markup, and previewing it in the editor never counts a view. The [views] shortcode is unchanged and still supported — nothing needs converting, and posts already containing it keep working.
  • NEW: A wp postviews WP-CLI command — list and get. It reads and never writes.
  • NEW: A postviews/v1 REST API carrying one route, for counting a view from a cached page. Reading a count is already a views field on the core post resource. The admin-ajax.php wp_postviews action is unchanged and still supported.
  • BREAKING: Requires WordPress 6.8 and PHP 8.2.
  • BREAKING: The the_views filter is now wp_postviews_the_views. The template tag the_views() is unchanged.
  • BREAKING: The postviews_should_count filter is now wp_postviews_should_count.
  • BREAKING: The postviews_increment_views and postviews_increment_views_ajax actions are now wp_postviews_increment_views and wp_postviews_increment_views_ajax.
  • BREAKING: The settings are stored in wp_postviews_options instead of views_options, and the upgrade markers in wp_postviews_version instead of views_version. Both are migrated automatically.
  • BREAKING: The WP-Stats toggles move out of the shared stats_display and stats_mostlimit rows into this plugin’s own settings, and the shared rows are deleted. Update all seven WP-Stats plugins together.
  • BREAKING: The widget class WP_Widget_PostViews is now WP_PostViews_Widget. Configured widgets are unaffected.
  • BREAKING: The AJAX action a cached page posts to is now wp_postviews instead of postviews.
  • BREAKING: The six Display Options settings — home page, single posts, pages, archives, searches and other pages — are removed, and the stored keys are dropped on upgrade. Their replacement is the wp_postviews_should_display filter.
  • NEW: Restructured into includes/ classes. The template tags — the_views(), get_most_viewed(), get_least_viewed(), and the category and tag variants — are unchanged and keep working exactly as before.
  • NEW: The options screen is rebuilt on the WordPress Settings API and no longer loads jQuery.
  • NEW: The WP-Stats section, and how many entries its most viewed lists carry, are now settings on Settings -> WP-PostViews.
  • NEW: The wp_postviews_should_display filter decides whether a count is shown. It is read by the_views() only; the [views] shortcode and the admin Views column are explicit requests and ignore it.
  • CHANGED: The settings screen is two tabs, Settings and Templates, over one settings group and one option row.
  • CHANGED: The settings screen is titled “Post Views Settings”, matching the other settings screens in this family.
  • CHANGED: WP-Stats now receives one Views section rather than three separately toggled panels, so the most viewed pages list appears alongside the posts list.
  • FIXED: %VIEW_COUNT_ROUNDED% picked its unit before rounding, so 999,950 displayed as “1000K” instead of “1M” and 999,999,999 as “1000M” instead of “1B”.
  • FIXED: Titles were truncated on bytes rather than characters, because the multibyte branch was gated on MB_OVERLOAD_STRING, which PHP 8.0 removed. A CJK title cut mid-character disappeared from the most/least viewed lists entirely.
  • FIXED: The AJAX endpoint recorded views against post IDs that do not exist, letting anyone add rows to wp_postmeta indefinitely.
  • FIXED: ?v_orderby=ASC was compared against lowercase only, so an uppercase direction — which is what the FAQ tells you to use — silently fell back to descending, the opposite of what was asked for.
  • FIXED: The widget silently discarded changes made in the block widget editor and the customizer, because it required a hidden form field neither of them sends.
  • FIXED: The widget warned about undefined array keys when rendered from the block widget editor or the customizer.
  • FIXED: Uninstalling on a network of more than 100 sites left options and view counts behind on every site after the hundredth, and reported success. Network activation could fatal on the removed wp_get_sites().
  • NOTE: The settings screen moved from options-general.php?page=wp-postviews/postviews-options.php to options-general.php?page=wp-postviews. Update any bookmark; the Settings -> WP-PostViews menu item is where it always was.
  • NOTE: Templates are now stored unslashed. Existing templates are migrated automatically the first time 2.0.0 loads.
  • NOTE: should_views_be_displayed(), postviews_round_number() and snippet_text() are no longer global functions. They were never documented; they are now WP_PostViews_Display::should_be_displayed(), WP_PostViews_Display::round_number() and WP_PostViews_Display::snippet_text().

Full changelog on WordPress.org →

Screenshots

Settings -> WP-PostViews, which chooses whose views are counted and how they are recorded
Settings -> WP-PostViews, which chooses whose views are counted and how they are recorded
The Templates tab, holding the wording the count is written into
The Templates tab, holding the wording the count is written into
The count in a post, placed with the shortcode
The count in a post, placed with the shortcode
The Most Viewed widget
The Most Viewed widget

For developers

Is this your plugin? Show off the numbers.

Add a live badge to your site, docs or GitHub README. It updates on its own — no account needed.

Active installs badge Rating badge Health score badge

Best WP-PostViews alternatives

All Counter plugins →
Alternatives
Rank Plugin Active installs Rating Updated Health
1 Post Views Counter Post Views Counter Post Views Counter allows you to collect and display how many times a post, page, or other… by dFactory 100K+ ★★★★★★★★★★ 4.9 (1.2K) 1 month ago 77
3 Simple Download Monitor Simple Download Monitor Easily manage downloadable files and monitor downloads of your digital files from your… by mra13 / Team Tips and Tricks… 20K+ ★★★★★★★★★★ 4.7 (156) 2 weeks ago 88
4 Counter Number Showcase, Fun Facts – WordPress Animated Counter Plugin Counter Number Showcase, Fun Facts Counter Number WordPress Plugin brings you all the powerful Stats Counter features to your… by wpshopmart 10K+ ★★★★★★★★★★ 4.6 (190) 2 years ago 48
5 SRS Simple Hits Counter SRS Simple Hits Counter Display unique visitor or page-view counts anywhere on your site using widgets or… by SandyRig 8K+ ★★★★★★★★★★ 4.2 (6) 4 months ago 66
6 Counter live visitors for WooCommerce Counter live visitors for WooCommerce Show user count on product by DanielRiera 4K+ ★★★★★★★★★★ 5 (5) 7 months ago 56
7 Post View Count Post View Count Add a "Post View Count" plugin to get the count of views for your posts. by Naresh Parmar 4K+ ★★★★★★★★★★ 4.6 (18) 2 weeks ago 71
8 Wp Post Views – WordPress Post views counter Wp Post Views – WordPress Post views counter WP Post Views is a lightweight and efficient plugin to track and display post views in… by Ronak J Vanpariya 4K+ ★★★★★★★★★★ 4.4 (7) 1 week ago 82
9 Counters Block – Animated Number Counters, Stats & Dynamic KPIs Counters Block Animated number counters for Gutenberg. Show stats, milestones, KPIs, and live WooCommerce… by bPlugins 3K+ ★★★★★★★★★★ 5 (8) 6 days ago 83
10 Light Views Counter – Fast, Scalable View Counter for High-Traffic Sites Light Views Counter Lightweight and fast post view counter with smart tracking, built for high-traffic sites… by ThemeRuby 3K+ ★★★★★★★★★★ No reviews 4 months ago 60
11 Counting Number Block Counting Number Block This block provides an animated counter effect for numbers. It’s fast, lightweight… by Phi Phan 2K+ ★★★★★★★★★★ 5 (9) 1 month ago 79

FAQ

WP-PostViews: quick answers

Straight answers, pulled from live WordPress.org data.

Live data from WordPress.org · checked Sep 28, 2026

Is WP-PostViews free?

Yes. WP-PostViews is free to download and use from the official WordPress.org plugin directory.

Is WP-PostViews safe to use in 2026?

Yes — WP-PostViews is a safe, well-maintained plugin to use in 2026. It runs on 100K+ sites, is rated 4.4/5 and was last updated 1 month ago, and scores 85/100 on our health check.

How many websites use WP-PostViews?

WP-PostViews is active on 100K+ WordPress websites and has been downloaded 3,484,576 times since it launched in February 2006. It was downloaded 11,465 times in the last 30 days.

Does WP-PostViews work with WordPress 7.1?

Yes. The developer has tested WP-PostViews up to WordPress 7.1.2, the latest release. It requires WordPress 6.8 or newer.

What PHP version does WP-PostViews need?

WP-PostViews requires PHP 8.2 or higher. Most hosts run PHP 8.x today, so it works on any modern WordPress hosting.

When was WP-PostViews last updated?

The latest version, 2.0.1, was released on August 24, 2026 (1 month ago).

Who makes WP-PostViews?

WP-PostViews is developed and maintained by Lester Chan.

What are the best alternatives to WP-PostViews?

The most popular alternatives to WP-PostViews are Post Views Counter (100K+ installs), Simple Download Monitor (20K+ installs) and Counter Number Showcase, Fu… (10K+ installs).

Powered by PageForge

Want thousands of pages that rank like these? Build them in an afternoon.

This directory runs on the same engine as PageForge. Turn any spreadsheet, CSV or API into thousands of fast, SEO-ready WordPress pages — with schema, internal links and AI-written copy baked in.

  • CSV, Google Sheets & API data sources
  • AI content, schema & internal links per page
  • Works with Elementor, Gutenberg, Yoast & Rank Math
  • Free on WordPress.org — no credit card
Sarah is here to help!
Hi there! 👋 Need help finding what you're looking for?
Sarah
Sarah
Online & Ready to Help
Hi there! 👋 Need help finding what you're looking for?

We'll use this to continue our conversation

Just now ✓ Verified

Join 500+ SEO Pros Scaling Their Strategy

Get exclusive programmatic SEO tactics, AI content workflows, and the latest PageForge updates delivered straight to your inbox. Stay ahead of the algorithm.

We care about your data in our privacy policy.