Random Product Sorting with Pagination

There are already a couple tutorials on this website related to product sorting, you can read for example, how to change a default sorting order, how to completely remove it or how to add a custom sorting option.

Today we are going to go even further and add an option to sort products in random order and retain it during pagination.

First things first, let’s add a new sorting option. There is another tutorial about that, so you can read more if you want. Right now we are going to do it with woocommerce_catalog_orderby filter hook.

add_filter( 'woocommerce_catalog_orderby', 'misha_random_sorting_option' );

function misha_random_sorting_option( $options ){
	$options[ 'rand' ] = 'Sort in a random order';
	return $options;
}

When we add sorting options, we can also use woocommerce_get_catalog_ordering_args to make the ordering work, but in this example we do not need it, because our random sorting happens on another level, with posts_orderby hook.

Now we already have some first results:

Add sort in a random order option

It is worth mentioning that if you with to reorder our custom sorting option, this guide will help you.

Ok, great now we already have a random sorting option but nothing is working.

Before we continue to the next and last code snippet I would like to introduce you RAND() function in SQL. It accepts the only parameter – seed. And once a seed is specified, the functions returns a repeatable sequence of random numbers. If not specified – a completely random number every time. So, it is the thing that allows us to retain the same products during pagination.

WordPress has a couple filter hooks that allow to modify SQL statements, here they are:

session_start();

add_filter( 'posts_orderby', 'misha_rand_order_with_seed' );

function misha_rand_order_with_seed( $orderby ){
	
	// do nothing if we are not on the shop page
	// you can include product archive pages here as well
	if( ! is_shop() ) {
		return $orderby;
	}
	
	// do the magic only when "Sort in a random order" is selected
	if( isset( $_GET[ 'orderby' ] ) && 'rand' === $_GET[ 'orderby' ] ) {
		// reset the order each time the 1st page is visited
		if( ! is_paged() && isset( $_SESSION[ 'seed' ] ) ) {
			unset( $_SESSION[ 'seed' ] );
		}
		$seed = false;
		if( isset( $_SESSION[ 'seed' ] ) ) {
			$seed = $_SESSION[ 'seed' ];
		}
		// Set a new seed if not exists
		if ( ! $seed ) {
			$seed = rand();
			$_SESSION[ 'seed' ] = $seed;
		}
		// pass it to an SQL query
		$orderby = 'RAND(' . $seed . ')';
	}
	return $orderby;
}

Keep in mind that posts_orderby is triggered everywhere, even in WordPress admin, so don’t forget about conditional statements, I uses is_shop() which means the Shop page, for WooCommerce you can also use is_product_category() or is_product_tag() depending on the page where youre going to implement the random posts order.

And yes, the code can be used not only for WooCommerce products but for any post types.

WooCommerce random product sorting with pagination in action
I tried to show on this GIF how it finally works. No products are being repeated on the other pages.
Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X