• tryhukigor

    (@tryhukigor)


    Hello,

    I am using WP Statistics 14.16.13 on a WordPress website with a custom news theme.

    I have implemented an infinite scroll for single news posts. The first post is loaded normally, so WP Statistics correctly records its view.

    All subsequent posts are loaded via AJAX without reloading the page.

    The flow is:

    1. User opens:
      /news/post-1/
    2. WP Statistics correctly records a view for post-1.
    3. User scrolls down and post-2 is loaded via AJAX.
    4. Then post-3, post-4, etc. are loaded via AJAX.
    5. When a new post becomes the currently viewed post, I also update the browser URL using history.replaceState():
      /news/post-2/
      /news/post-3/

    The problem is that WP Statistics continues to record views for the initially opened page, while the AJAX-loaded posts do not receive their own view count.

    I display the post statistics using:

    wp_statistics_pages('total', null, get_the_ID())

    For AJAX-loaded posts, get_the_ID() is correct and returns the ID of the specific post being rendered.

    Each AJAX-loaded post also contains its own URL:

    <div
        class="singleNews-block"
        data-url="https://example.com/news/post-2/"
        data-title="Post 2"
    >

    The browser URL is changed with:

    history.replaceState(
        { url: url },
        '',
        url
    );

    I also tried using the WP Statistics REST endpoint:

    /wp-json/wp-statistics/v2/hit

    However, the request does not associate the hit with the required post_id. Instead, the view continues to be attributed to the initially opened post.

    I need the following behavior:

    Initial post #1
    → WP Statistics +1 for post ID #1
    
    AJAX-loaded post #2
    → when it becomes the currently viewed post
    → WP Statistics +1 for post ID #2
    
    AJAX-loaded post #3
    → when it becomes the currently viewed post
    → WP Statistics +1 for post ID #3

    The page itself is never reloaded.

    Is there an official PHP API, REST API, hook, or internal method in WP Statistics 14.16.13 that can be used to manually register a view for a specific WordPress post ID during AJAX/infinite-scroll navigation?

    I specifically need a method where I can provide the post_id and record the view for that particular post, rather than having WP Statistics determine the post from the current HTTP request URL.

    Could you please provide an example implementation compatible with WP Statistics 14.16.13?

    Thank you.

    The page I need help with: [log in to see the link]

Viewing 1 replies (of 1 total)
  • Plugin Author Mostafa Soufi

    (@mostafas1990)

    Hi, thanks for the detailed write-up, it made this easy to follow.

    You don’t need a separate API for this. WP Statistics already listens to history.replaceState(). When the URL changes, it re-reads its tracking data from the wp-statistics-tracker-js-extra script tag and sends a new hit. Your infinite scroll changes the URL but not that tag, so the hit still carries post 1’s ID. Update the tag right before replaceState() and each post gets its own view.

    1. PHP, where you render each AJAX-loaded post**, add the tracking data to the post’s wrapper:

    php
    $post_id     = get_the_ID();
    $source_type = \WP_STATISTICS\Pages::get_post_type( $post_id );
    $wps_hit     = array(
        'source_type' => $source_type,
        'source_id'   => $post_id,
        'signature'   => \WP_Statistics\Utils\Signature::generate( array( $source_type, $post_id ) ),
    );
    
    printf( '<article class="news-post" data-wps-hit="%s" data-url="%s">', esc_attr( wp_json_encode( $wps_hit ) ), esc_url( get_permalink( $post_id ) ) );
    

    2. JS, when a post becomes the current one**, update the tracker data, then change the URL as you do now:

    js
    function wpsTrackPost(article) {
        var tag = document.getElementById('wp-statistics-tracker-js-extra');
        if (tag && window.WP_Statistics_Tracker_Object) {
            var data = JSON.parse(JSON.stringify(WP_Statistics_Tracker_Object));
            Object.assign(data.hitParams, JSON.parse(article.dataset.wpsHit));
            tag.textContent = 'var WP_Statistics_Tracker_Object = ' + JSON.stringify(data) + ';';
        }
    
        var url = article.dataset.url;
        history.replaceState({ url: url }, '', url);
    }
    

    The order matters: update the tag first, then call replaceState(). Only call it once per post, so scrolling back and forth doesn’t count extra views.

    We tested this on 14.16.x: each replaceState() then records a view for the right post ID, and wp_statistics_pages('total', null, $post_id) counts it.

    Let us know how it goes.

Viewing 1 replies (of 1 total)

You must be logged in to reply to this topic.