Randomising the order of the returned posts in a WordPress query is easy – simply add
'orderby' => 'rand' to the arguments and you’re good to go – this is great, until you need to paginate the results. As soon as you navigate to the second page of the results, the posts are returned randomly once again and you get an entirely different set of posts that may or may not contain posts that you have already viewed – if you’ve experienced this before then you’ll know exactly how frustrating it can be. After having this problem numerous times myself I decided to find a way around it.
The first thing we need to do is make sure our PHP session is initiated. You will see the reason for this in the function itself, which is where the magic happens – here we will use MySQL’s RAND() function and supply it with a seed value so it uses the same random order on every subsequent page load. To do this we will store a random string as a PHP session variable so it can be used by MySQL as a reference for the order to use for each page. All we need to do is add this snippet to our theme’s functions.php file:
You will notice one extra operation on line 7 of this snippet – we also reset the seed value every time the first page of the posts are loaded. This means that as long as someone stays on the paginated pages they will see a consistent set of results, but once they go back to the first page the randomisation will reset and they will see the posts in a completely different order.
Note that in this example I have limited the ordering to the front page only (that is, the home page of the site when the front page is set to show your latest posts), but you can change the conditional to target any page or post type archive that you like.