1. Block Spam Views with REST Nonce Verification — Optional, Zero Overhead When Off
One persistent issue with view-counting plugins is spam requests: bots or scripts POST directly to /wp-json/initvico/v1/count without ever loading the page, completely bypassing the scroll + 15-second delay mechanism. Starting with 1.21, admins can enable the “Require REST nonce verification?” option under Settings → Init View Count to mandate that every request to the /count endpoint carry a valid X-WP-Nonce header.
The critical detail: this option is off by default. The reason is practical: WordPress nonces expire after roughly 12–24 hours. If your site uses full-page caching (LiteSpeed, WP Rocket, Cloudflare APO, etc.) with a long TTL, stale cached pages will carry an expired nonce. When that happens, legitimate user view-count requests are also rejected with 403 until the cache refreshes. The plugin only outputs the nonce via wp_localize_script() when the option is enabled — when disabled, there is zero overhead in code or requests.
The GET /top endpoint is intentionally excluded from this mechanism because it is read-only and public by design (top-viewed post lists), carrying no spam-write risk.
2. Performance Optimization: From Read-Then-Write to Atomic SQL
Before 1.20, each view was processed in a two-step sequence: get_post_meta() reads the value → update_post_meta() writes value + 1. Under high-traffic conditions, two requests could both read 100 and both write 101 — the result only increments by 1 instead of 2. This is the classic race condition.
Starting with 1.20, the plugin switches to a raw SQL statement:
UPDATE wp_postmeta SET meta_value = meta_value + 1 WHERE post_id = ? AND meta_key = ?
This statement is atomic at the database layer — MySQL guarantees that no two transactions read the same old value and overwrite each other. The result: 100% accuracy even when 100 simultaneous requests hit the same post.
Beyond the atomic update, three additional optimizations were made:
- Client return value is computed locally (
cached value + 1) instead of re-querying the database after the write, saving oneSELECTper key. - Object cache invalidation runs exactly once per post per request after all keys (total, day, week, month) are updated, instead of four separate invalidations.
- Traffic Shape Learner (the module that learns traffic distribution by hour and day of week) now buffers view counts throughout the request and flushes exactly once on the
shutdownhook, instead of callingget_option()/update_option()for every post in a batch.
For sites using batch tracking (aggregating 5–10 views before sending to the server), the reduction in option writes is substantial — especially valuable for high-traffic installations.
3. Complete i18n: POT Source + Vietnamese PO/MO
Version 1.21 adds previously missing English source strings to languages/init-view-count.pot, including two critical REST API messages: "Invalid post ID." and "Not enabled for view counting.". At the same time, a Vietnamese translation (init-view-count-vi.po / .mo) is shipped out of the box, so Vietnamese-language sites can display error messages and the admin interface entirely in their native language.
4. REST API Code Path Hardening
The entire REST API code path has been audited against WPCS (WordPress Coding Standards). Every direct SQL query carries a detailed phpcs:ignore justification, so code-review teams and CI/CD pipelines understand exactly why a rule is being bypassed. No behavior changes were introduced for existing filters or actions — all legacy hooks continue to work exactly as before.
Should You Update Now?
Yes. 1.21 is a hotfix + optimization release with no backward-compatibility breaks. Sites running 1.19 or 1.20 can update directly via the WordPress Dashboard or manual upload. The only caveat: if you enable “Require REST nonce verification?”, ensure your full-page cache TTL is under 12 hours, or configure periodic cache purging.
Init View Count 1.21 is available now on the WordPress Plugin Directory and the official GitHub repository. The full changelog and detailed upgrade guide are available on the plugin’s Settings page.
Comments