WordPress post meta makes it easy to store and retrieve per-post data. Tracking view counts without a plugin is simpler than most developers think and avoids the overhead of a full analytics plugin for simple use cases.
The Approach
We store the view count in WordPress post meta, increment it on each single post view, and retrieve it anywhere using get_post_meta(). Total implementation: about 20 lines of PHP.
The Code
Add to functions.php:
/**
* Track post view count using post meta
* smjrifle — smjrifle.xyz/
*/
function smjrifle_track_post_views($post_id) {
if (!is_single()) return;
if (empty($post_id)) {
global $post;
$post_id = $post->ID;
}
// Don't count admin views or bot traffic
if (is_user_logged_in() && current_user_can('edit_posts')) return;
$count = (int) get_post_meta($post_id, 'smj_view_count', true);
$count++;
update_post_meta($post_id, 'smj_view_count', $count);
}
add_action('wp_head', 'smjrifle_track_post_views');
/**
* Get view count for a post
*/
function smjrifle_get_view_count($post_id = null) {
if (!$post_id) $post_id = get_the_ID();
$count = (int) get_post_meta($post_id, 'smj_view_count', true);
return $count > 0 ? number_format($count) : '0';
}
Display the Count in Your Template
<?php if (is_single()): ?>
<span class="view-count">
<?php echo smjrifle_get_view_count(); ?> views
</span>
<?php endif; ?>
Show Popular Posts in Sidebar
$popular = new WP_Query([
'posts_per_page' => 5,
'meta_key' => 'smj_view_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
]);
Limitations
This approach counts page loads, not unique visitors. It doesn’t filter bots reliably beyond logged-in users. For production analytics, use a proper solution (Plausible, Fathom, or GA4). But for a lightweight “popular posts” widget with no third-party dependencies? This is clean and fast.