Currently, you can use a widget or a block to have the user see the list of products they recently viewed.
But for now, let’s create our own shortcode… and let’s take advantage of the existing [products] shortcode and learn how we can “pass” product IDs to it without the need of reinventing the wheel.
This snippet teaches you how to store data in a custom cookie, and also how to output a core shortcode… inside a custom shortcode. Enjoy!

PHP Snippet: [recently_viewed_products] Shortcode
/**
* @snippet [recently_viewed_products] Shortcode - WooCommerce
* @how-to businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 8
* @community https://businessbloomer.com/club/
*/
add_action( 'template_redirect', 'bbloomer_track_product_view', 9999 );
function bbloomer_track_product_view() {
if ( ! is_singular( 'product' ) ) return;
global $post;
if ( empty( $_COOKIE['bbloomer_recently_viewed'] ) ) {
$viewed_products = array();
} else {
$viewed_products = wp_parse_id_list( (array) explode( '|', wp_unslash( $_COOKIE['bbloomer_recently_viewed'] ) ) );
}
$keys = array_flip( $viewed_products );
if ( isset( $keys[ $post->ID ] ) ) {
unset( $viewed_products[ $keys[ $post->ID ] ] );
}
$viewed_products[] = $post->ID;
if ( count( $viewed_products ) > 15 ) {
array_shift( $viewed_products );
}
wc_setcookie( 'bbloomer_recently_viewed', implode( '|', $viewed_products ) );
}
add_shortcode( 'recently_viewed_products', 'bbloomer_recently_viewed_shortcode' );
function bbloomer_recently_viewed_shortcode() {
$viewed_products = ! empty( $_COOKIE['bbloomer_recently_viewed'] ) ? (array) explode( '|', wp_unslash( $_COOKIE['bbloomer_recently_viewed'] ) ) : array();
$viewed_products = array_reverse( array_filter( array_map( 'absint', $viewed_products ) ) );
if ( empty( $viewed_products ) ) return;
$title = '<h3>Recently Viewed Products</h3>';
$product_ids = implode( ",", $viewed_products );
return $title . do_shortcode("[products ids='$product_ids']");
}
Was looking for this, given the old widget way is no longer working in the current theme Iâm using. Amazing resource, thank you!
I simply want to show the âlatest ONEâ product only, not a list, and followed what others said, including trying to remove âarray_reverseâ you suggested, but it is still showing the last product of the start of the cache session â and not the last product I viewed as I navigate around the products. Is there a better way to only show the âpreviousâ one viewed?
Can you not get the first array element with $array[0]?
Hello dear Rodolfo! Thank you very much for this awesome piece of code!
I would love it if it worked as well for cached products and had its own class. Still awesome for cases in which my claims are not requested.
Best regards
You’re welcome!
hi, it doesnt work anymore. adding it to snippet
You’re right! Snippet updated
hi how i use it?
i just add code to function.php file.
Hi Amin, you also need to place the related shortcode somewhere in your website – let me know
hello,
thank you for the nice code, i have implemented it into my website and it works nicely
but the most recently viewed products seem to not be shown but only the oldest recently viewed products. and since i have limited the dislay to 5, i always see “old” products. is there a way to fix this?
thanks
maria
Try remove the “array_reverse(” call and the final “)” on that same line once you do that. Let me know
For people who can’t filter the number of products displayed. You have to insert the restrictions in the function.php and not in the shortcode.
Change for example the last line of the code given at the top of the page by :
And to make it work, I personally had to add the code given in karolina’s comment.
Here, good luck
I just tried it on one of my stores, and didn’t worked as expected. It displayed all the products in the store, and wasn’t able to set a cookie either.
Hopefully, someone will be able to suggest a work around? and if somehow it can be fixed to set the number of columns, that will be great!
Thanks
Hi Tanveer, that’s weird. Can you try with a different theme and no other plugins than Woo?
Hi
I needed to remove one of the double square brackets? (I’m not native english) in the return function.
return $title . do_shortcode(“[[products ids='$product_ids']]“);
->
But really thanks for this code! (and other snippets! very usefull!)
Kind regards
Thanks! Fixing that now
Hi,
Thank you for putting this code free on this website. I am currently using it and am happy with its effect.
There is just 1 thing I would like to know, or like to add: it would be really great if there was an “else” statement with a fallback shortcode to display when somebody hasn’t viewed any products yet.
With the code as it is, it will display an empty field when a new visitor comes to the site. Maybe you could make it fallback to orderby=”popularity” with beste_selling=”true” for example?
I don’t have the PHP knowledge to do this myself.
Hello Vinnie, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hi,
This code used to work on my site but all of a sudden not anymore. Is anyone experieing the same thing?
Just updated to woocommerce 4.8.0
Thanks.
experiencing*
I find it strange. If you rollback to a previous version of WooCommerce does that work?
How do you change the order of the products to be by the order they were viewed?
So the last viewed product (excluding currently viewed product) is the first on the list.
Is the current sorting the opposite i.e. last viewed is last?
for me the order is kind of random.
is where a way to limit the shown products to 5?
How kann i change the display grid for the products from 3 to 5?
Thank you for the help
Hi Chris: https://docs.woocommerce.com/document/woocommerce-shortcodes/#section-11
I did so [recently_viewed_products limit = “4” columns = “3”] but it didn’t work properly. what should I do. Thank you
Hello Viet, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
This tutorial feels incomplete with no clear way for a non coder to display the amount of products desired.
Without being able to control the amount of items the code can not be of any real use.
You are sending everyone to the WordPress codex that talks about short codes but the answer is not there.
I am pretty sure a lot of people including myself tired: [recently_viewed_products limit = â4â columns = â3â] .
Consider updating your tutorial so that it is friendly to us who are new to coding.
No tutorial is incomplete đ I do my best
hey, its working but it just showing the product ID , not showing the product image
Disable all plugins but Woo and try again please
$product_ids = implode( “,”, $viewed_products= array_slice($viewed_products, 0, 4) );
This show the latest item, how to do display view item from left to right?
Hi Allan, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
hello,
Can you tell me how to display the recently viewed products on a single page as Amazon is doing ?
It seems better to have only 1 page than a widget, and exclude this page from cache.
Thank you.
Hi, can you use my shortcode on that page?
Great snippet! I tried to limit the number of products to 4, but I didn’t succeed.
Can anyone help me?
Thanks!
You should study this and change the “return” part of the snippet accordingly: https://docs.woocommerce.com/document/woocommerce-shortcodes/#section-6
Hi,
i have added your code, but when i see my website and without viewing any products today the history tab will be blank, that means when i visit some products yesterday , they will not showup in history tab, only the today’s viewed products is seen, otherwise the page getting blank . please help me as soon as possible.
WooCommerce sets a cookie, so if your browser clears cookies or such cookie lasts for only 24 hours, there is no solution to your problem. Sorry
You should add `orderby=’post__in’` to the shortcode attributes, otherwise it will sort posts by title. There is an `array_reverse` used in code but it’s pointless without this attribute
Ah nice, good to know Nick! Thank you
You are just awesome!
Thank you so much for this website…helped me out so many times! đ
Great!
Hi Rodolfo :), great snippet!
I’ve discovered that the “woocommerce_recently_viewed” cookie is stored only when the Recently viewed products widget is in use. If you want to use your code without the widget, you need to track the viewed products by your own: https://github.com/woocommerce/woocommerce/issues/9724 So you might add a note about it to the post đ
Cheers from Prague!
KarolĂna
Ahoy Karolina! Thanks so much for this, I will add it in the notes đ
Hi there,
I just added the code to my child functions.php file. But in several browsers the recently viewed product does not show up.
I added the shortcode into the html of my homepage to make them visible over there. But not showing.
What am I doing wrong?
Thank you in advance.
Hi Steff, maybe you have cookies disabled?
Hello, Rodolfo
I added the code in funcions.php and it is working, but I would like to control the quantity of products displayed and limit the 1 line, since it is showing all products recently viewed and this is loading the page a lot. In case I added it to the cart page! how to control the boundaries of displayed products and limiting the display to only 01 line on desktop and Mobile (with arrows for side drag) ?? thank you
Hi Joao, just add parameters to the returned shortcode: https://docs.woocommerce.com/document/woocommerce-shortcodes/#section-8
Thanks for the code. When I echo the [recently_viewed_products] shortcode it orders the products by name in ASC. Is this normal behaviour? When I var_dump $product_ids the order is ok, but $product_ids are used in [products ids='$product_ids'] shortcode, the order changes to product name. Is there any solution for ordering by view?
Not perfect solution, but I have limited the number of products in the $viewed_products array.
$viewed_products = array_slice($viewed_products, 0, 5);
Now the [recently_viewed_products] shortcode displays the latest 5 recently viewed products. Order is not correct but now it shows the latest 5 products.
Cool!
Thanks Karesz and Rodolfo, I have add Karesz line:
“$viewed_products = array_slice($viewed_products, 0, 5);” and it have limit viewed product to 5, but I don’t know how to adjust the amount of product per line. Can you provide a code to adjust that? Thanks!
How can I display only image of “Recently Viewed Products”, without Titles and Prices?
Hello Valentine, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Thanks for the code. The shortcode only works for me when I have the WooCommerce recently viewed widget active on a sidebar somewhere in my site. Otherwise it seems the cookie doesn’t get created. Is this normal behaviour?
Thanks
Hi Nick. By looking at the function wc_track_product_view(), this triggers on the single product page OR if the widget is active, so it should work no matter what. Let me know
how do i put it on widget sidebar ?
Hello Arie, in the sidebar you can actually use the WooCommerce “Recently Viewed” widget
I am using Widgets to show Recent Viewed Product on right side on the shop page.
Cool! This, instead, is a shortcode than can be used on a page/post too