Track Profile Views in ProfileBuilder with a JetEngine-Powered Shortcode (No Plugin Bloat)
Track Profile Views in ProfileBuilder with a JetEngine-Powered Shortcode (No Plugin Bloat)

Want to show how many times each user profile has been viewed—without a heavy analytics plugin? Here’s a clean, copy-paste solution using a simple PHP snippet, AJAX, and a shortcode you can drop right into your Profile single page. It works with ProfileBuilder and stores counts in user meta, updating only once per visitor per 24 hours to avoid spammy repeat hits.

What You’ll Build

A PHP snippet you can add via your favorite snippets plugin

An AJAX endpoint that increments the view count safely

A shortcode [user_profile_view_count] to display the number on the profile page

Smart logic that accepts user ID, username, or nicename from the URL

Prerequisites

WordPress + ProfileBuilder (for user profiles)

JetEngine (we’re following its naming/usage patterns)

A snippets plugin (e.g., Code Snippets, WPCode)

Your Profile single page must pass a user identifier in the URL (e.g., jet_pb_user=123 or slug/username)

Step 1: Create a PHP Snippet

Copy the full code below.

Create a new snippet in your snippets plugin.

Paste the code, set it to run on the front end, and save/activate.

				
					// Function to handle AJAX request for updating user profile views
function ajax_update_user_profile_views() {
    // Check the nonce for security
    check_ajax_referer('update_profile_view_nonce', 'nonce');

    // Get the user identifier from the AJAX request
    $user_identifier = isset($_POST['user_identifier']) ? sanitize_text_field($_POST['user_identifier']) : '';
    $identifier_type = isset($_POST['identifier_type']) ? sanitize_text_field($_POST['identifier_type']) : '';

    // Strict input validation for identifier_type
    if (!in_array($identifier_type, ['id', 'nicename', 'username'], true)) {
        wp_send_json_error('Invalid identifier type');
        return;
    }

    if ($user_identifier && $identifier_type) {
        // Get the user ID based on the identifier type
        $user_id = 0;
        switch ($identifier_type) {
            case 'id':
                $user_id = intval($user_identifier);
                break;
            case 'nicename':
                $user = get_user_by('slug', $user_identifier);
                if ($user) {
                    $user_id = $user->ID;
                }
                break;
            case 'username':
                $user = get_user_by('login', $user_identifier);
                if ($user) {
                    $user_id = $user->ID;
                }
                break;
        }

        // Validate user existence
        if ($user_id && get_userdata($user_id)) {
            // Define the meta keys for storing view counts and last view time
            $meta_key_count = 'jet_profile_views_count_engine';
            $meta_key_last_view = 'jet_profile_last_view_time_engine';

            // Get the current view count and last view time
            $view_count = get_user_meta($user_id, $meta_key_count, true);
            $last_view_time = get_user_meta($user_id, $meta_key_last_view, true);

            // Get the current time
            $current_time = time();

            // If no view count exists, initialize it to 0
            if ($view_count === '') {
                $view_count = 0;
            }

            // Check if this is a new view (more than 24 hours since last view)
            $time_threshold = 24 * 60 * 60; // 24 hours in seconds

            if (empty($last_view_time) || ($current_time - intval($last_view_time)) > $time_threshold) {
                // Increment the view count
                $view_count++;
                // Update the user meta with the new view count and current time
                update_user_meta($user_id, $meta_key_count, $view_count);
                update_user_meta($user_id, $meta_key_last_view, $current_time);
            }

            // Return the current view count
            wp_send_json_success($view_count);
        } else {
            wp_send_json_error('User not found');
        }
    } else {
        wp_send_json_error('Invalid user identifier or identifier type');
    }
}

// Hook the AJAX function for logged-in users and guests
add_action('wp_ajax_update_user_profile_views', 'ajax_update_user_profile_views');
add_action('wp_ajax_nopriv_update_user_profile_views', 'ajax_update_user_profile_views');

// Shortcode to display user profile view count
function user_profile_view_count_shortcode() {
    // Get the current user identifier from the URL
    $user_identifier = get_query_var('jet_pb_user');
    if (!$user_identifier) {
        return ''; // Return nothing if no user identifier is found
    }

    // Determine the identifier type
    $identifier_type = 'id'; // Default to ID
    if (!is_numeric($user_identifier)) {
        $identifier_type = username_exists($user_identifier) ? 'username' : 'nicename';
    }

    // Get the user ID
    $user_id = 0;
    switch ($identifier_type) {
        case 'id':
            $user_id = intval($user_identifier);
            break;
        case 'nicename':
            $user = get_user_by('slug', $user_identifier);
            if ($user) {
                $user_id = $user->ID;
            }
            break;
        case 'username':
            $user = get_user_by('login', $user_identifier);
            if ($user) {
                $user_id = $user->ID;
            }
            break;
    }

    if (!$user_id) {
        return ''; // Return nothing if no valid user is found
    }

    // Generate a nonce for security
    $nonce = wp_create_nonce('update_profile_view_nonce');

    // Inline JavaScript to trigger AJAX on page load and update display every 30 seconds
    ob_start(); ?>
    
        jQuery(document).ready(function($) {
            function updateViewCount() {
                $.post('', {
                    action: 'update_user_profile_views',
                    user_identifier: '',
                    identifier_type: '',
                    nonce: ''
                }, function(response) {
                    if (response.success) {
                        $('#profile-view-count').text('This profile has been viewed ' + response.data + ' times.');
                    } else {
                        console.error('Error updating view count:', response.data); // Error handling
                    }
                }).fail(function(jqXHR, textStatus, errorThrown) {
                    console.error('AJAX request failed:', textStatus, errorThrown); // Error handling
                });
            }

            // Initial update
            updateViewCount();

            // Update display every 30 seconds
            setInterval(updateViewCount, 30000);
        });
    
    <?php

    // Get the initial view count to display
    $view_count = get_user_meta($user_id, 'jet_profile_views_count_engine', true);
    $view_count = $view_count ? $view_count : 0;

    // Return the view count with a placeholder for dynamic updates
    return &#039;<p id="profile-view-count">This profile has been viewed ' . esc_html($view_count) . ' times.</p>';
}

// Register the shortcode
add_shortcode('user_profile_view_count', 'user_profile_view_count_shortcode');

				
			

Step 2: Add the Shortcode to Your Profile Single Page

Open your Profile single template (the one ProfileBuilder uses for individual user pages) and place this shortcode where you want the count to appear:

[user_profile_view_count]

Step 3: Make Sure the URL Provides a User Identifier

The shortcode looks for a jet_pb_user query var in the URL. Examples that will work:

  • example.com/profile/?jet_pb_user=123 → ID
  • example.com/profile/?jet_pb_user=john → username
  • example.com/profile/?jet_pb_user=john-doe → nicename (slug)

If your template doesn’t already set jet_pb_user, adjust your routing or add it in your link generation so the page loads with that parameter.

How It Works (In Plain English)

  • When the profile page loads, the shortcode prints a placeholder and injects a small JS script.
  • The script calls WordPress AJAX (admin-ajax.php) with a secure nonce and the current profile’s identifier.
  • The PHP handler validates inputs, resolves to a reliable user_id, and updates two user meta keys:
  • jet_profile_views_count_engine → total views
  • jet_profile_last_view_time_engine → timestamp of the last counted view
  • It only increments the counter if at least 24 hours have passed since the last view, preventing rapid repeat counts.
  • The latest count is shown in place, and the script refreshes it every 30 seconds in case multiple visitors land while the page is open.

Customization Tips

  • Change the displayed sentence by editing the final return line in the shortcode output.
  • Want a different cooldown window? Tweak 24 * 60 * 60 to your desired seconds.
  • Prefer server-side render only? Remove the JavaScript block and display get_user_meta directly—but you’ll lose the live refresh.

Troubleshooting

  • Seeing nothing? Ensure the URL has jet_pb_user and that it matches an existing user.
  • Console error “Invalid identifier type”? Check the value passed for identifier_type in the AJAX call (the snippet handles it automatically).
  • AJAX blocked? Make sure your snippet runs on the front end and that no security plugin is blocking admin-ajax.php.

SEO Snippet to Reuse in Your Listing Page

Add a small callout near each profile link like “Viewed X times” by calling the same meta key server-side if you already know the user ID:

$views = (int) get_user_meta( $user_id, 'jet_profile_views_count_engine', true );
echo 'Viewed ' . $views . ' times';

You’re Set

You now have a lightweight, secure way to display profile views in ProfileBuilder with JetEngine conventions—no extra analytics plugin required. Want me to turn this into a Gutenberg/Elementor block with a settings panel next?

Faqs