Mục lục
Vì sao không nên dùng page view thông thường?
| Phương pháp | Vấn đề |
|---|---|
| Đếm mỗi lần truy cập | Tính cả bot, reload, thoát nhanh → sai lệch rất nhiều. |
| Đếm lượt cuộn qua đoạn giữa | Không kiểm soát được thời gian thực sự đọc. |
Mục tiêu
- Chỉ tính 1 lượt đọc nếu người dùng ở lại ít nhất X giây
- Và đã cuộn qua ít nhất Y% độ dài bài viết
Ý tưởng kỹ thuật
- Gắn listener scroll và timer
- Khi đã scroll qua ≥ 75% nội dung và ở lại ≥ 15 giây, gọi API đếm 1 view
- Dùng cookie hoặc sessionStorage để không đếm lặp nhiều lần
Đoạn code thêm vào footer.php
<?php if (is_single()) : ?>
<script>window.post_id = <?= get_the_ID(); ?>;</script>
<?php endif; ?>
Đoạn code JavaScript mẫu
(function () {
if (!window.post_id) return;
const key = `viewed_${window.post_id}`;
if (sessionStorage.getItem(key)) return;
let scrollPassed = false;
let timePassed = false;
let alreadySent = false;
// Sau 15 giây
setTimeout(() => {
timePassed = true;
triggerCount();
}, 15000);
// Scroll vượt 75%
window.addEventListener("scroll", () => {
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const scrolled = window.scrollY;
if ((scrolled / docHeight) > 0.75) {
scrollPassed = true;
triggerCount();
}
});
function triggerCount() {
if (scrollPassed && timePassed && !alreadySent) {
alreadySent = true; // đảm bảo không gửi nhiều lần
fetch('/wp-json/custom/v1/count-read', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ post_id: window.post_id })
}).then(() => {
sessionStorage.setItem(key, "1");
});
}
}
})();
Tạo endpoint REST API để xử lý
add_action('rest_api_init', function () {
register_rest_route('custom/v1', '/count-read', [
'methods' => 'POST',
'callback' => 'custom_count_post_read',
'permission_callback' => '__return_true'
]);
});
function custom_count_post_read($request) {
$post_id = absint($request->get_param('post_id'));
if ($post_id) {
$views = (int) get_post_meta($post_id, '_true_read_count', true);
update_post_meta($post_id, '_true_read_count', $views + 1);
return rest_ensure_response(['status' => 'ok']);
}
return new WP_Error('invalid', 'No post ID', ['status' => 400]);
}
Hiển thị lượt đọc thực tế
<?php
$read = (int) get_post_meta(get_the_ID(), '_true_read_count', true);
echo "Bài viết đã được đọc thật sự: " . number_format($read) . " lượt.";
?>
Không phải lượt view nào cũng là một lượt đọc thật sự. Hãy chọn cách đếm thông minh để biết bài viết nào thực sự có giá trị với độc giả!
Gợi ý nâng cao
- Tùy chỉnh tỷ lệ scroll (%), thời gian ở lại tuỳ theo độ dài bài viết
- Gắn thêm check nếu user tương tác (bấm nút, copy đoạn…) để tăng độ chính xác
- Lưu IP hash để chống spam
- Hiển thị biểu đồ heatmap đọc bài nếu muốn phân tích sâu
Với giải pháp trên, bạn không chỉ biết bài viết nào được click, mà còn thực sự được đọc và quan tâm. Đó mới là giá trị thật sự.
Bình luận