How to Add Products Per Page Dropdown to Woocommerce

This is going to be a very quick tutorial that will show you how to add the ability to Woocommerce for users to select the amount of products shown per page.

We will be using the built in Woocommerce hooks and filters and set a cookie via php so the browser can remember the selection across the website. We will be trying to add this into a plugin in the near future but until that time, follow along and edit as you see fit.
Major thanks to bcworkz for his help with setting the cookies and just being awesome!

so here we go, in your themes functions.php file let’s add the following little snippet:

// Lets create the function to house our form
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );

function woocommerce_catalog_page_ordering() {
<?php echo '<span class="itemsorder">Items Per Page:' ?>
    <form action="" method="POST" name="results" class="woocommerce-ordering">
    <select name="woocommerce-sort-by-columns" id="woocommerce-sort-by-columns" class="sortby" onchange="this.form.submit()">
//Get products on page reload
if  (isset($_POST['woocommerce-sort-by-columns']) && (($_COOKIE['shop_pageResults'] <> $_POST['woocommerce-sort-by-columns']))) {
        $numberOfProductsPerPage = $_POST['woocommerce-sort-by-columns'];
          } else {
        $numberOfProductsPerPage = $_COOKIE['shop_pageResults'];
//  This is where you can change the amounts per page that the user will use  feel free to change the numbers and text as you want, in my case we had 4 products per row so I chose to have multiples of four for the user to select.
			$shopCatalog_orderby = apply_filters('woocommerce_sortby_page', array(
			//Add as many of these as you like, -1 shows all products per page
			  //  ''       => __('Results per page', 'woocommerce'),
				'20' 		=> __('20', 'woocommerce'),
				'-1' 		=> __('All', 'woocommerce'),

		foreach ( $shopCatalog_orderby as $sort_id => $sort_name )
			echo '<option value="' . $sort_id . '" ' . selected( $numberOfProductsPerPage, $sort_id, true ) . ' >' . $sort_name . '</option>';

<?php echo ' </span>' ?>
// now we set our cookie if we need to
function dl_sort_by_page($count) {
  if (isset($_COOKIE['shop_pageResults'])) { // if normal page load with cookie
     $count = $_COOKIE['shop_pageResults'];
  if (isset($_POST['woocommerce-sort-by-columns'])) { //if form submitted
    setcookie('shop_pageResults', $_POST['woocommerce-sort-by-columns'], time()+1209600, '/', '', false); //this will fail if any part of page has been output- hope this works!
    $count = $_POST['woocommerce-sort-by-columns'];
  // else normal page load and no cookie
  return $count;
add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_page_ordering', 20 );


I tried to keep it well documented so if you have any questions feel free to let me know and I can make the edits as they come. I hope this helps, Because I wanted this located next to the “Sort by” dropdown I used the “before_shop_loop” action then styled it in place via css. You can always change this depending on your needs by just changing that hook.


  1. James on February 26, 2013 at 12:49 am

    Great piece of code. this was very helpful. Thanks.

    Is there a way for the drop down to display the current selection amount. meaning if i changed it to display 36 per page and it reloads the page to display that amount, can the drop down now show 36 as the “current” selection instead of showing the first/base number?


    • Derek Schmidt on March 4, 2013 at 2:13 pm

      Hey James, Yes there is definitely a way, it would be very similar to the way Woocommerce does it in their ‘sort-by’ select. I thought I had already implemented that in there but if you want to double check, look in your woocommerce files -> templates and in one of those folders is the sorting.php file. Going off memory here but if you open that up you will see how Woo did it with their drop-down. I know the code above is setup for that but there must be a small error in there somewhere or within setting the cookie and that is why their choice is not present in the dropdown when the screen reloads. As soon as I get some free time I will put Woo back on local host and get that worked out but I do not have any active installs with Woocommerce still on them. I will trouble shoot and let you know and likewise if you get this resolved before me. Many thanks!

      • James on September 30, 2013 at 9:07 pm

        Hi Derek,

        Did you ever get a chance to look at having the dropdown display the currently selected option instead of the first option?

        I have looked at the sorting.php and it looks very close to your code and I did not see any particular difference that would indicate what is having it display the current selection. perhaps it is just not working on my site. if so how would I find out why?

        Thanks again!

        • Derek Schmidt on October 3, 2013 at 3:51 am

          You can try it with javascript, something similar to the below

          var select_id = document.getElementById("woocommerce-sort-by-columns");
          Hope this helps
  2. Marcel on March 23, 2013 at 7:53 pm

    Hi Thanks for this code. I am also curious of the solution to show the current selected number. In my case it does not store the cookie value som somehow it resets to the default 10 all the time with page switches. Do you have a hin were to find this issue?

    • Derek Schmidt on March 23, 2013 at 7:57 pm

      Other users have reported this issue and it has typically been a theme or plugin conflict. Try switching to the default twenty twelve and see if that fixex it, if not then try deactivating all plugins and enable one at a time until you find the problem. If you find the conflicting theme/plugin then post here so we can work on resolving it.

  3. Marcel on March 23, 2013 at 8:42 pm

    Have done some debugging and found that the cookie simply did not store… then I saw the ‘’, replaced it with mine….

    and it worked like a charm… Now the only wish is to get the default value in… I’ll check if I can find a solution for that.

  4. Marcel on March 23, 2013 at 10:16 pm

    Found the issue… don’t know if it is the best solution but it works for me.. Have added checks for my new display_count vars and used this one to match the selected value. Defaulted to 24 and took out the blank one. Works perfect for me. Hope it helps you. Had to add the post check because the session var was one lap behind the real value.

    Thanks for your effort and sharing…!

    // Lets create the function to house our form
    function woocommerce_catalog_page_ordering() {

    __(’24 per pagina’, ‘woocommerce’),
    ’48’ => __(’48 per pagina’, ‘woocommerce’),
    ‘-1’ => __(‘Alles tonen’, ‘woocommerce’),

    foreach ( $shopCatalog_orderby as $sort_id => $sort_name )
    echo ” . $sort_name . ”;

    ….. rest of code is still the same

    • Derek Schmidt on March 23, 2013 at 11:13 pm

      Glad you got it working, thanks for sharing the solution

  5. luke on April 22, 2013 at 9:47 am

    Thanks for this it is great, except it is messing up my pagination. When I select next page, or page 2 etc.. I get a 404 error…

    Any ideas what is happening there?


    • Derek Schmidt on April 22, 2013 at 10:55 am

      Hey Luke, did you replace the “” with your own?

  6. Zach on April 30, 2013 at 3:53 am

    Hey guy’s this code works great. I have the same issues as everyone else when it resets back to 10 items i would like the default to be 12. Would be great to see this working 100% the smallest things seem to be the biggest headaches in wordpress lol. Other then that the plugin/hack is pretty nice and does do the job. I did change the web addy and tried to add the folder url also. But that did nothing still does not work. All I really need is for it to show 12 items and not 10.

  7. Derek Schmidt on April 30, 2013 at 3:58 am

    Hey Zach, try adding this to your themes functions.php file:

    // change default number of products per page
    add_filter( 'loop_shop_per_page', create_function( '$cols', 'return 12;' ), 20 );

  8. Zach on April 30, 2013 at 3:25 pm

    I did that but the dropdown stops working. It will show 12 items but it will not let me change to 20 or 30 if i wanted.

    • Derek Schmidt on May 1, 2013 at 2:58 am

      Could you paste your functions.php to a pastebin and I can check it out? Either that or post both snippets of here

  9. Zach on May 1, 2013 at 4:28 am

    Here it is the default Twenty Eleven theme i used.

  10. Zach on May 1, 2013 at 7:06 pm

    yes the plugin works cookies work find. but if you clear your cookies or start on a new browser default still shows 10. i was wondering how i can get that to show 12 and still have it so the dropdown works.

    • Derek Schmidt on May 1, 2013 at 7:25 pm

      Oh i see, so you need to place the add_filter within the function like so:

      dont forget to change your domain name back πŸ™‚

  11. Zach on May 4, 2013 at 3:14 am

    You can delete my previous comment above this. I figured out how to allways display 12 items in your store. The default is set to 10 so what you should do is go into your admin dashboard. Locate settings,reading and change posts and items to 12 or whatever default number you may want. This has saved me and this plugin works great! No need to add the default woocommerce one this one works like a charm and without that annoying code they provided us lol.

    • Derek Schmidt on May 4, 2013 at 12:05 pm

      Wow, lol I have been pecking away at it this morning trying to over complicate things and sometimes it is the most simplest solution that ends up working out. Thanks for sharing Zach, take care!

  12. Zach on May 5, 2013 at 12:39 am

    Same Derek i over think on coding and bam its all ways the simplest thing all ready coded for you. But those cookies you figured out work like a charm for when people select certain numbers. Thats one bad thing with me in coding i think it has to be hard then turns out it’s a 1,2 punch type of deal lol.

  13. Adrian on June 11, 2013 at 11:43 pm

    Hey guys!
    First of all, Derek, thank you so much for this awesome tweak!

    Second, I would like to share my workaround/hack for the number of products/page select value resetting every time the page refreshes.

    So, at first, I tried passing the $_COOKIE[‘shop_pageResults’] var via javaScript and forcing the select to keep the cookie value.

    The issue here was that, by sending the value using $_POST, the $_COOKIE[‘shop_pageResults’] was always updating one step behind.

    So, I added some if/then/else magic inside your woocommerce_catalog_page_ordering function like so:

    if (isset($_POST[‘woocommerce-sort-by-columns’]) && (($_COOKIE[‘shop_pageResults’] $_POST[‘woocommerce-sort-by-columns’]))) {
    $currentProductsPerPage = $_POST[‘woocommerce-sort-by-columns’];
    } else {
    $currentProductsPerPage = $_COOKIE[‘shop_pageResults’];

    Then I forced the value of $currentProductsPerPage into the select option via javascript.

    Of course, you can customize this to your own needs, but basically this does the trick.

    Happy coding!

    • Derek Schmidt on June 12, 2013 at 12:28 am

      Awesome! Nice work, thanks for sharing πŸ˜‰

    • Chris on June 12, 2013 at 1:36 am


      Thanks for the hint on how to make this work. I get a parse error in the first line of your code:

      if (isset($_POST[‘woocommerce-sort-by-columns’]) && ($_COOKIE[‘shop_pageResults’]
      $_POST[‘woocommerce-sort-by-columns’]))) {

      which makes it fail.

      Also, if you dont mind me asking? What was the javascript you used to change the selected state?


      • Derek Schmidt on June 12, 2013 at 2:01 am

        Hey Chris, the JS should be in the line of code from above.. The reason you are getting the parse error is because there is nothing separating the $_COOKIE and the $_POST.. Try adding the & in between like so:
        if (isset ($_POST['woocommerce-sort-by-columns']) && (($_COOKIE['shop_pageResults'] & $_POST['woocommerce-sort-by-columns']))) {
        $currentProductsPerPage = $_POST['woocommerce-sort-by-columns'];
        } else {
        $currentProductsPerPage = $_COOKIE['shop_pageResults'];

        You just need to add Adrians snippet to the function woocommerce_catalog_page_ordering().. Probably before the closing bracket that closes the function.

        • Adrian on June 12, 2013 at 4:54 am

          Thanks a lot, Derek, you’re right! That’s the issue because probably the comment area of your website probably doesn’t process “greater than” and “lower than” characters put together.

          The main if statement should look like this:

          if (isset($_POST[‘woocommerce-sort-by-columns’]) && (($_COOKIE[‘shop_pageResults’] [] $_POST[‘woocommerce-sort-by-columns’]))) {

          Without the brakets around the gt and lt chars. Basically you wanna test if you’re on the first page refresh after applying a product per page number.

          If the $_POST is set and $_POST is not equal to what you have stored in the $_COOKIE, then echo $_POST, else echo $_COOKIE.

          Also, Chris, I used jQuery’s .attr method to force the select:

          $(‘select.sortby>option:eq(1)’).attr(‘selected’, true);

          Here’s the reference:

          And you can find a working example over here:

          Have fun!

          • Adrian on June 12, 2013 at 5:01 am

            To avoid further confusion, you can find the if logic here:

          • Chris on June 12, 2013 at 8:51 pm

            Thanks a bunch Adrian! Those examples really helped.

  14. Chris on June 12, 2013 at 2:45 am

    Thanks Derek! That works.. !

    Odd though, I dont see the JS in that post from Adrian.. Wonder if it is being filtered?

  15. andres on June 27, 2013 at 8:30 pm

    There is an easiest way to fix the number of products per page…. change the number of posts in blog… settings –> Reading (sorry im spanish, not sure if that is what it says on english wordpress) and that is it

    • Derek Schmidt on June 29, 2013 at 1:44 pm

      thx andres, this is aimed towards having the front end user select the amount of product they want displayed per page, but your answer works for changing the default number of products per page.

  16. daniel on July 30, 2013 at 10:47 am

    Hi, this is just what iv been looking for but i cant get it working!
    iv added your code to functions.php and changed the website to mine but still nothing?

    do you have any idea why this might be ?

    could really do with some help thanks…

    • Derek Schmidt on July 30, 2013 at 1:45 pm

      Hi Daniel, I checked the site and did not see the selection box for products per page. If you want to add it and give it another shot then let me know when to check it I will be more than happy to try and help you out.

      • daniel on July 31, 2013 at 5:37 am

        Hi Derek, this is the problem am having i cant get it to show, not sure what am doing wrong… iv added your code to the function.php file and changed url but still nothing?

  17. James Kember on July 30, 2013 at 11:17 am

    Thanks guys, awesome work around. Why this isnt already a plugin is beyond me. Can anyone tell me how instead of 24, 35, 48 etc, I can just have 20, 40, 60 and the most importantly ‘show all’ and it actually returns all my products?

    • Derek Schmidt on July 30, 2013 at 1:46 pm

      You should just be able to change the numbers from 24, 35, 48, .. to 20, 40, 60, 80, …

      There should not be anything else you have to do. Let me know if it works.

  18. James Kember on July 30, 2013 at 2:27 pm

    Thanks Derek, but how do i actually have the text saying ‘show all’ rather than putting in a high number. For example if have 140 products in total I don’t want to put 80 in as it won’t show them all. If I put in 140 sure it will show them all but i don’t want to have to keep adjusting that everytime I add a product. Hope the makes sense.

    • Derek Schmidt on July 30, 2013 at 2:34 pm

      Should be something like this I believe:

      apply_filters('woocommerce_sortby_page', array(
      			    ''       => __('Results per page', 'woocommerce'),
      				'20' 	=> __('20 per page', 'woocommerce'),
      				'40' 		=> __('40 per page', 'woocommerce'),
      				'60' 		=> __('60 per page', 'woocommerce'),
      				'-1' 		=> __('Show All', 'woocommerce'),
  19. James Kember on July 30, 2013 at 3:36 pm

    Perfect thanks Derek, you da man!

  20. ashfaq ahmed on August 13, 2013 at 7:30 am

    Hi, you have done great work πŸ™‚ but is there a way to add this into any theme file ? thanks

    • Derek Schmidt on August 13, 2013 at 12:34 pm

      Sure, assuming this is still for woocommerce shop you can just put this anywhere you want it to display:

      < ?php woocommerce_catalog_page_ordering() ?>
  21. Scott Weiss on September 12, 2013 at 4:16 pm

    Derek, I ran into an issue. Let’s say you have 49 results, and each page has 12 results, and you’re on the last page (page 5). So you’re viewing the 49th result. Then you select show all (or show 64). It doesn’t bring you back to the first page. It stays on page 5 and shows page not found. Is there a way to make it go back to the first page or previous page that has results?

    • Derek Schmidt on September 12, 2013 at 7:11 pm

      I dont have anywhere to test this with Woocommerce isntalled at the moment but you can try something like this:

      // now we set our cookie if we need to
      function dl_sort_by_page($count) {
        if (isset($_COOKIE['shop_pageResults'])) { // if normal page load with cookie
           $count = $_COOKIE['shop_pageResults'];
        if (isset($_POST['woocommerce-sort-by-columns'])) { //if form submitted
        	$shop_page_url = get_permalink( woocommerce_get_page_id( 'shop' ) );
          setcookie('shop_pageResults', $_POST['woocommerce-sort-by-columns'], time()+1209600, '/', $shop_page_url, false); //this will fail if any part of page has been output- hope this works!
          $count = $_POST['woocommerce-sort-by-columns'];
        // else normal page load and no cookie
        return $count;

      Note the $shop_page_url variable we defined in the function that handles the cookies. Make sure the above replaces the similar code in the markup. If that doesnt work 100% possible try the wp_redirect within that function.

      Good luck

      • Scott Weiss on September 17, 2013 at 2:59 pm

        Well, the shop page wasn’t the issue that would solve it, and in fact in order for the cookie to be set properly the shop page url needs to just be the domain name (like originally) which i was dynamically able to get by using $domain_name = preg_replace(‘/^www./’,”,$_SERVER[‘SERVER_NAME’]);

        But this still leads me to that redirect after the count is set. I just don’t think it will work, and i’m not an expert in this, but i’ll get some help and see what i can do. I’ll let you know.

  22. Dave on October 16, 2013 at 11:01 am

    This doesn’t work for me πŸ™ Select the drop down and nothing happens, still showing “Showing 1-12 of 200 results”

    • Derek Schmidt on October 17, 2013 at 1:30 pm

      Hey Dave did you replace the domain in the source code with your own? Also make sure you have cookies and javascript enabled in your browser.

  23. gayatri on December 5, 2013 at 7:53 pm

    Hi, Derek i have read comments & try to solve issue but not get result what i have issues is it takes value 10 from “the default Blog pages show at most” & “posts Syndication feeds show the most recent” i have changed the it’s value but it takes the value of wordpress blog post set valued not our drop down selected value . please help me to solve this issue .

    site url :

  24. Peej on February 9, 2014 at 9:43 pm

    So I had success with this snippet on my default theme, but once I switch on my custom theme (its called Salient), the dropdown menu does not reload the page with the appropriate number of items. I just get the default 12. Any ideas?

    • Derek Schmidt on February 10, 2014 at 1:44 pm

      Hmm, do you have cookies and JS enabled on your browser? Have you changed the url in the snippet to be the new url you are loading it too? Have you checked your developer console for any other javascript conflicts? If yes then you may have a JS conflict which is preventing the rest of the JS on the page to load. I personally use Firebug to debug.

      • Peej on February 11, 2014 at 6:48 am

        Hi Derek, thanks for your reply. I confirmed all the things you mentioned and agree that it is a js conflict. I’m recommending to check the console errors between the two themes and further, the js versions between the two. If you have any other ideas, please feel free to reply. Otherwise, I will report back with my findings. Thanks!

  25. daniel on February 10, 2014 at 9:27 am

    can not seem to get the select to show what you have selected on reload always defaults to the first one even tho the page is showing “all”

    any idea ?

    • Derek Schmidt on February 10, 2014 at 1:48 pm

      I think someone had found another solution for this, try looking here: and see if that helps you. Also verify the cookie has been set with your browsers developer tool

      • daniel on February 12, 2014 at 2:16 am

        Not sure if my reply went through the other day…
        did not understand #comment 1260? when i added the script i just see errors and dose not look right…

        iv pasted my code here…

        hope are able to help thanks

        • Derek Schmidt on February 16, 2014 at 1:03 am

          Hey daniel, sorry busy week.. Can you email me a link to the site? I would be more than happy to take a look, the first step is checking to see if the cookie is even setting when the drop down is fired. Email me and I will try to help you get it worked out.

          • daniel on February 17, 2014 at 5:27 am

            Derek, just sent you an email. thanks

  26. Annie on February 27, 2014 at 11:05 pm

    Hi and thanks for this code! However things dont go as they should?
    Standard it shows 12 items, and as long as you keep that and hit next everytime it works fine, also just selecting show all works fine too.

    However, as soon as you select lets say 8 then on the bottom select next, it resets every time to 12 again. I suppose it should keep showing 8 even after hitting next.

    But where it really messes up is if at first it shows 8, then after hitting next its adds 12 again, if you hit/select 8 per page again, it messes the count up. If it was at 12 items and you select then lets say 32 the next page it skips from 13 to 33, so it does not show numbers 13 to 32 all of the sudden it starts showing 33 to 64.

    So it is all messed up and misguides clients for they dont see/skip a lot of products this way.

  27. Annie on February 27, 2014 at 11:11 pm

    I used this code by the way:

    // User selects how many products to view per page

    // via

    function woocommerce_catalog_page_ordering() {


    __(‘Producten per pagina’, ‘woocommerce’),

    ‘8’ => __(‘8 per pagina’, ‘woocommerce’),

    ’16’ => __(’16 per pagina’, ‘woocommerce’),

    ’32’ => __(’32 per pagina’, ‘woocommerce’),

    ‘-1’ => __(‘Alle producten’, ‘woocommerce’),


    foreach ( $shopCatalog_orderby as $sort_id => $sort_name )

    echo ” . $sort_name . ”;


    <?php // Adrian's code

    if (isset($_POST['woocommerce-sort-by-columns']) && (($_COOKIE['shop_pageResults'] $_POST[‘woocommerce-sort-by-columns’]))) {

    $currentProductsPerPage = $_POST[‘woocommerce-sort-by-columns’];

    } else {

    $currentProductsPerPage = $_COOKIE[‘shop_pageResults’];



    jQuery(‘select.sortby>option[value=””]’).attr(‘selected’, true);



    // now we set our cookie if we need to

    function dl_sort_by_page($count) {

    if (isset($_COOKIE['shop_pageResults'])) { // if normal page load with cookie

    $count = $_COOKIE['shop_pageResults'];


    if (isset($_POST['woocommerce-sort-by-columns'])) { //if form submitted

    setcookie('shop_pageResults', $_POST['woocommerce-sort-by-columns'], time()+1209600, '/', '', false); //this will fail if any part of page has been output- hope this works!

    $count = $_POST['woocommerce-sort-by-columns'];


    // else normal page load and no cookie

    return $count;


    add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_page_ordering', 20 );


  28. Annie on February 27, 2014 at 11:13 pm

    It would be awesome if there was a plugin that did this, without having to dive into code? No plans yet, haha πŸ™‚

    • Derek Schmidt on March 1, 2014 at 10:51 pm

      Hey Annie, did you get your issue resolved? Maybe I can package this into a plugin soon — just been super busy lately which is why I am a bit late approving and replying to my comments πŸ˜‰

      • Annie on March 5, 2014 at 4:44 pm

        Hi Derek,

        Thx for your reaction, I did not get a notification so just found it by accident!

        No, it is not resolved, I use the code, see link above in test site please, but it does not work properly. As soon as I click on next it messes up the count.

        I know a lot of people would like this as a plugin, because in large shop, this is a must have.

        If you could develop a plugin, I am pretty sure lots of users would like to pay for this option if it is per license and affordable.

        It would mean a lot to me if you would concider developing this in the near future. Do you think you might want to take time to do this?


  29. Jeroen on March 6, 2014 at 7:37 pm

    Hi Derek,

    I’ve made a plugin wich does this exactly and a bit more. I would like to share it with the people here to use without needing to code.

    • Derek Schmidt on March 7, 2014 at 6:16 pm

      Thanks Jeroen, looks good! Alot of people have been asking for this so I am glad someone had the time to put something together.

  30. Arvind Prajapti on October 16, 2014 at 7:35 am

    thank you for the great coding of that.My site is now on my localhost. i have page template where i have to added a sorting drop-down. But its only reload the page not working in my page.Please give me the solution of that.

  31. Daniel on August 18, 2015 at 1:09 pm

    πŸ˜› I don’t know any coding so excuse me, where do I add this code in the editor? After a certain line or something because I added it to the top and nothing happened……

    • Daniel on August 18, 2015 at 1:17 pm

      ok I looked it up it says put it anywhere…. That doesn’t work either

Leave a Comment