Updated on 6 Mar 2024
This Pro tutorial provides the steps to output the most recent x number of posts (can be of any specified post type) viewed by the current visitor (need not be logged-in) in a Bricks query loop.
We shall use cookies to track the posts viewed. If you have a GDPR cookie notice in place and the user has yet to agree to store the cookies on their computer, this solution won’t work. In such a case, there will be simply no output.
Update 1: Added instructions for showing the recently viewed products.
Step 1
Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:
<?php
add_action( 'template_redirect', function () {
// Check if the current page is a single post
if ( ! is_singular( 'post' ) ) {
return;
}
// Get the current post ID
$post_id = get_the_ID();
// Empty array to store the recently viewed posts
$recently_viewed = [];
// If the 'recently_viewed' cookie is set
if ( isset( $_COOKIE['recently_viewed'] ) ) {
// Decode the JSON-encoded 'recently_viewed' cookie, removing any slashes added by WordPress for security, and convert it to an array.
$recently_viewed = json_decode( wp_unslash( $_COOKIE['recently_viewed'] ), true );
}
// Prepend the current post ID to the recently viewed posts array
array_unshift( $recently_viewed, $post_id );
// Remove duplicates
$recently_viewed = array_unique( $recently_viewed );
// Limit the array size to 5 posts
$recently_viewed = array_slice( $recently_viewed, 0, 5 );
// Set or update the cookie with the new list
// This line sets a cookie named 'recently_viewed' with the JSON-encoded array of recently viewed post IDs,
// expires in 7 days, and is available across the entire domain. It also sets the cookie to secure if the site is accessed via HTTPS.
setcookie( 'recently_viewed', json_encode( $recently_viewed ), time() + 3600 * 24 * 7, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
} );
// Function to check if a given cookie is set
function bl_is_cookie_set( $cookie_name ): string {
return isset( $_COOKIE[$cookie_name] );
}
Set your desired post type in if ( ! is_singular( 'post' ) ) {.
Replace 5 with the number of desired posts that should be shown.
Step 2
Set up a query loop in a Template/Page where you’d like to output the 5 most posts that the visitor has recently viewed.
Enable PHP query editor and paste:
return [
'post_type' => 'post', // your post type here
'posts_per_page' => 5, // posts per page here
'no_found_rows' => true,
'post__in' => json_decode( wp_unslash( $_COOKIE['recently_viewed'] ), true ),
'orderby' => 'post__in',
];
Select the Section (or any other element of your choice) that should be output only if there is at least 1 post in the recently viewed cookie for the current visitor.
Apply this dynamic data condition:

{echo:bl_is_cookie_set(recently_viewed)}
Note: If a post page is open the first time it is considered a view. If the user leaves this post open in a tab, visits another page in the site, and returns to the post, it does not count as a view. For it to be considered a view, it must be reloaded.
Update 1
For showing recently viewed products
If you use a query loop change
if ( ! is_singular( 'post' ) ) {
to
if ( ! is_singular( 'product' ) ) {
If you use a Products element, add this code:
add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
if ( $element_id === 'kgwlzp' ) {
$query_vars['no_found_rows'] = true;
$query_vars['post__in'] = json_decode( wp_unslash( $_COOKIE['recently_viewed'] ), true );
$query_vars['orderby'] = 'post__in';
}
return $query_vars;
}, 10, 3 );
Replace kgwlzp with the Bricks ID of the query loop-enabled element.
