Beginner's Guide for WordPress / Start your WordPress Blog in minutes

How to Display Popular Posts by Views in WordPress (2 Ways)

Do you want to display popular posts by views in WordPress?

Displaying your popular posts can help you generate more traffic, keep visitors on your site longer, and build social proof.

In this article, we’ll show you how to display your popular posts by views in WordPress, both with and without a plugin.

How to display popular posts by views in WordPress (2 ways)

Why Display Popular Posts by Views in WordPress?

Sometimes it can be hard for your visitors to find your best content. Even your most popular articles can get lost when you have thousands of blog posts.

Displaying your most popular posts lets you show your most popular articles anywhere across your WordPress blog.

Your popular posts are the most successful pieces of content for a reason. By displaying these to your visitors, you’ll build trust, improve social proof, and ensure that your visitors stay on your website longer.

Popular posts example

When your visitors stay on your WordPress website longer, this gives you more time to convince them to make a purchase, join your email newsletter, or take another action.

With that said, let’s take a look at how to simply display popular posts by views in WordPress using 2 methods.

Click on the quick link to jump straight to your preferred method:

Video Tutorial

Subscribe to WPBeginner

If you’d prefer written instructions, just keep reading.

Method 1: Display Popular Posts by Views With a Plugin in WordPress

There are many WordPress popular posts plugins that you can use to display your most popular content, but the easiest plugin to use is MonsterInsights.

MonsterInsights is the best analytics solution for WordPress used by over 3 million websites. It lets you simply display your popular posts anywhere on your WordPress site.

Inline popular posts example

You can also use the Inline Popular Posts feature to show your popular posts directly within your content.

First thing you need to do is install the plugin. For more details, see our step by step guide on how to install Google Analytics in WordPress for beginners.

Note: there is a free version of MonsterInsights available, but we’ll be using the pro version since it includes the popular post feature.

Upon activation and set up, go to Insights » Popular Posts and then click the ‘Popular Posts Widget’ menu item.

Select popular posts widget

On this screen, you can select the popular post style you want to use. This will control the appearance of your popular posts.

There are a lot of additional customization options as well.

For example, under the ‘Theme Preview’ meta box, you can display your popular posts in a ‘Wide’ format below your content, or on the right hand side of your page with the ‘Narrow’ option.

Theme preview box MonsterInsights

Next, you can change the color and size of the post title, author, and date.

The ‘Widget-Layout Options’ menu will change the the number of columns that are displayed. There are additional display options you can customize on this screen as well.

MonsterInsights will automatically save all settings after you make a change.

Popular posts additional display settings

Once you’ve customized the appearance of your popular posts, you’ll have a few different methods for adding them to WordPress.

In the ‘Embed Options’ meta box, there are 4 different display options. You can even use multiple display options together. The simplest way is turning on the ‘Automatic Placement’ toggle.

Embed Options meta box

You can also display popular posts using Gutenberg Blocks in the new WordPress editor, with a shortcode, or by adding the widget to a sidebar.

To display your popular posts using Gutenberg Blocks open up a post or page you want to edit.

After that, click the ‘Add Block’ icon.

Add Gutenberg popular posts block

Search for ‘popular posts’ in the search bar and then choose the ‘Popular Posts’ or ‘Inline Popular Posts’ option.

Then, in the right hand sidebar, you can further customize the appearance of your popular posts.

Customize popular posts appearance

The settings are similar to the settings from the MonsterInsights plugin menu we highlighted above.

After you’ve finished adding and customizing the appearance of your popular posts, make sure you click ‘Publish’ or ‘Update’ to save your changes.

Now, your visitors will see your popular posts when they visit your website.

Method 2: Display Popular Posts by Views Without a Plugin in WordPress

If you don’t want to use a plugin, or you’re already using too many plugins, then you can use this code method.

There are some downsides to using this method. First, it involves adding code to WordPress, and it’s not beginner friendly.

Second, the code method isn’t as performance optimized as MonsterInsights plugin, so it will increase server load and can slow down your site if you have a lot of content.

With that said, let’s take a look at how to add popular posts in WordPress without a plugin.

In this method, you’ll need to add code to your WordPress files. If you haven’t done this before, then check out our beginner’s guide to pasting snippets from the web into WordPress.

Now that you know how to add code in WordPress, let’s go ahead and add the following code to your functions.php file, in a site-specific plugin, or by using a code snippets plugin.

function wpb_set_post_views($postID) {
    $count_key = 'wpb_post_views_count';
    $count = get_post_meta($postID, $count_key, true);
        $count = 0;
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, '0');
        update_post_meta($postID, $count_key, $count);
//To keep the count accurate, lets get rid of prefetching
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0);

The code above will detect post view counts and store it as a custom field for each post.

Once you add that function to WordPress, you need to call the function on your single post pages. Now, you need to tell the function which post gets credit for the views.

To do this, copy and paste the following code inside your single post loop.


If you are using a child theme, or you just want to make things easy for yourself, then you should simply add the tracker in your header by using wp_head hook.

To do this paste the following code in your theme’s functions.php file or the site-specific plugin (as shown above):

function wpb_track_post_views ($post_id) {
    if ( !is_single() ) return;
    if ( empty ( $post_id) ) {
        global $post;
        $post_id = $post->ID;    
add_action( 'wp_head', 'wpb_track_post_views');

Once you have placed this, every time a user visits the post, the custom field will be updated.

Note: If you are using a caching plugin, then this technique will not work by default. You could use Fragmented Caching feature that’s offered by some advanced caching plugins to bypass the caching plugins.

Now, you can do all sort of cool stuff such as display post view count, or sort posts by view count. Let’s take a look at how to do some of these cool things.

You can display the post view count on your single post pages, often next to the comment count, or your social share buttons.

To do this, add the following in your theme’s functions.php file or the site-specific plugin (highlighted above).

function wpb_get_post_views($postID){
    $count_key = 'wpb_post_views_count';
    $count = get_post_meta($postID, $count_key, true);
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, '0');
        return "0 View";
    return $count.' Views';

Then inside your post loop add the following code:


If you want to sort the posts by view count, then you can do so easily by using the the wp_query post_meta parameter.

The most basic example loop query would look like this:

$popularpost = new WP_Query( array( 'posts_per_page' => 4, 'meta_key' => 'wpb_post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC'  ) );
while ( $popularpost->have_posts() ) : $popularpost->the_post();



To add other WP_Query parameters such as time range, refer to the WP_Query page in the Developers Handbook.

We hoped this article helped you learn how to display popular posts by views in WordPress. You may also want to see our guide on how to improve your WordPress SEO rankings, and our expert picks of the must have WordPress plugins for business websites.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

Disclosure: Our content is reader-supported. This means if you click on some of our links, then we may earn a commission. See how WPBeginner is funded, why it matters, and how you can support us. Here's our editorial process.

The Ultimate WordPress Toolkit

Get FREE access to our toolkit - a collection of WordPress related products and resources that every professional should have!

Reader Interactions

154 CommentsLeave a Reply

  1. Hello,
    I’ve using this code for months and it’s work greats! That’s until I start using W3 Total Cache and this code stop count views for me.
    I’m struck at where do I need to put the mfunc to let the code work with cache. Can you point that out?
    FYI, I put all the code in a site-specific plugin.

  2. hello, I have some problem on how setting up like when the login user won’t include on the count while viewing any pages?? how to do that.. please need some help on these. thanks

  3. Hey there, thanks for this. REALLY helpful!! Would you know how to apply a time range to this code? For example to show the most popular posts in the last day, week or month etc? I know there are plugins for this but I would like to do it without one :)

  4. Hello,
    thanks for this nice tutorial. It works on my page!

    – how can I exclude robots and spiders that hit my posts?
    – May be I can set a timer of 10 seconds. after that the count should rise. So the people who only click thourgh the posts are not counted.


  5. Hello – thanks so much for this! I noticed the question regarding the W3TC workaround, but have a slightly different question: does that still apply if I’m hooking into wp_head from functions.php, and if so, how exactly do I implement it there? Thank you!

  6. Hello, thanks for this snippet.

    I have a problem, the orderby don’t work. I have five posts :
    – Post 1 : 85 views
    – Post 2 : 35 views
    – Post 3 : 165 views
    – Post 4 : 1 view
    – Post 5 : 1 view

    When i displayed it the order was : 1, 2, 4, 5 and 3

    Do you have an idea please ?

  7. following your article I am using post view count in my site since 6 months. It was working fine, but recently I am having problem with this. If a visitor view a post the count is increasing by 1 but the problem is the count is increasing in all other posts. I have w3 total installed and I m using mfunc according to your article. Please help me if you have any idea about this issue… Thanks.

  8. Hello,
    I am wanting to switch from using the plugin because it doesn’t support the polylang language (the author’s not getting back to me and I don’t really know if it’s possible to filter functions for the plugin..)
    Two questions:
    – I examined the code a bit and I’m not sure if this code starts counting posts from when it’s implemented? Or does it somehow retrieve where the post counts are currently?
    – The current code on this website uses the get_posts() function so it creates an args array instead of using WP_Query(). Is this the same thing? I’m guessing not. And if it isn’t is the code below correct to get the array? I tried implementing this but it didn’t seem to work.
    $args = array( ‘meta_key’ => ‘wpb_post_views_count’, ‘orderby’ => ‘meta_value_num’, ‘order’ => ‘DESC’,’numberposts’ => 6, ‘post_status’=>”publish”,’post_type’=>”post”,’lang’ => ‘en’);

  9. This approach is very basic. If you want to count clicks from the same user (same IP) only every 5 minutes or 10 minutes etc. you need to have a separate table for that and before adding a new row in db you need to check the ip and time. If there is a record saved 3 minutes ago, the click is not added. Otherwise, it is added. Also this aproach allows you to create custom list of most viewed articles in 7 dyas, month, all time etc. Or even by category, user etc. (if you store appropriate values in appropriate table columns.

  10. i am trying .. when you say put code wpb_set_post_views(get_the_ID()); inside of single post loop, does that mean use this code inside of the theme single.php anywhere?
    thank you for your help

  11. Is there a way of restricting when the post views are collected from? For example, I am looking to display the posts with the most views in the last 24 hours, how would you do something like that using this code?

    Great post by the way, really helpful!

  12. What if your single-xxxx.php doesn’t use the loop but custom fields. How can I use this code if I don’t use the loop?

  13. What about using update_post_meta function instead of delete_post_meta and add_post_meta ?

  14. Thanks for this post! Really really good.
    I’ve two question:

    1. Is there any possibility to count just one visit for each IP adress? How?.
    2. Can i show the most popular posts by a specific period of time? For example, most visited posts this month, or the most popular posts from 1 of may to 1 of june…

    Thank you!

  15. Hi,
    This code is working but whenever i reload the page , it is adding “2” to the total page count. For example if page count is 14 and after reloading total page count is 16 … can anyone guess where’s the problem ?

    Shishir Umrao

  16. Very useful post, I managed to make my Tag pages to order posts by a custom field value similar to post view count, however, I ave pagination on my tag pages and it keeps showing the same top ranking posts on all pages, even after I have removed this code:

    ‘posts_per_page’ => 4,

    How do I fix the pagination so it show other posts on subsequent Tag pages?

    • How did you manage to make your Tag pages order posts by a custom field value similar to post view count?

      It looks like the popular posts plugin only takes categories as a parameter.

  17. Thanks for the very detailed instructions. Will using this to display the most popular posts cause a lot of additional server load if a site has significant traffic? Some of the WP plugins for this sort of thing tend to have this problem.

  18. I’m still learning this stuff so pardon my ignorance.

    How do you allow the user to choose between queries like they do on codecanyon when they allow you to sort by price, sales, date etc.?

    Thanks so much.

  19. Thank you so much for this. Life saver and a great tip that I definitely will be using more often.

  20. Hi , that’s great !
    But ‘orderby’ => ‘wpb_post_views_count meta_value_num’ not working.
    please use : ‘orderby’ => ‘meta_value_num’

  21. Thanks, it works for me, just with one important exception – popular posts are not as links, just their titles. How can I fix this, please?

  22. I added this code in the manner described in the article and upon activation, I saw this….

    The plugin generated 2 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.

    • Fixed. I did two things:

      1. Switched my permalink structure to a custom structure /%category%/%postname%/
      2. Check through all of my pages for extra spaces.

      One of them worked.

      …go figure


  23. Hi, I think it´s necesary add – wp_reset_query(); – at the end of the query to destroys the previous query used on a custom Loop.

    I hope It helps somebody.

  24. I have this working to 95% using a custom WP Query to display popular posts from each category.

    The only bit not working for me is the order – mine won’t display in descending order of views.

  25. Thanks for the post! This really helped.

    I’m not sure if anyone else ran into this issue, but when you set up the arguments for WP_Query, you have orderby => ‘wpb_post_views_count’. This was a problem for me because I wasn’t sure how it was ordering my posts. In the codex it says that if your using numbers they will only sort by the first digit. To fix this, you can simply replace the ‘wpb_post_views_count’ with ‘meta_value_num’. This basically will tell the query to reach inside the post’s meta value and probably cast it to an integer before it sorts. Hope this helps anyone running into the same issues.

    Overall, it works great! I have the 4 most popular posts in a slider on the home page. Thanks again!

      • Hi. Your code sample up top is *not * updated.

        Instead of this:

        ‘orderby’ => ‘wpb_post_views_count meta_value_num’

        you should have this as suggested :

        ‘orderby’ => ‘meta_value_num’

        if you want to sort by “Most to Least”

  26. This looks great on my home page but it seem to want to display on my single.php or anywhere else on my site. I tried creating a sidebar-single.php and inserting the code but still no luck. Any idea why it wouldn’t work on other areas my theme?

    • This usually happens when meta key wpb_post_views_count is not available for posts, make sure you add the function that tracks views within wp while loop, otherwise it will keep showing random posts.

      – Mody

      • Hello,
        I’m using your code for track post view in the wordpress theme.

        function wpb_get_post_views($postID){
        $count_key = ‘wpb_post_views_count’;
        $count = get_post_meta($postID, $count_key, true);
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, ‘0’);
        return “0 View”;
        return $count.’ Views’;

        The problem is that when I use W3 Total Cache the track view is not working right.

        Is there a way in the W3 Total Cache’s Options to put ignore only on this function, but in the same time I want the code to work with W3 Total Cache?

        Thank you!

  27. Hello
    i followed your tutorials and have done exactly what u said.
    i also added ur snippet
    php query_posts(‘meta_key=post_views_count&orderby=meta_value_num&order=DESC’);
    in index.php

    i am facing a little error,
    i am using infinite scrolling
    when i put this snippet in index.php
    the infinite scroll instead of loading next set of post
    loads the same sets of post

    For better Understanding u can check it live here

  28. For some reason my post views are incrementing by 2 on each page refresh. What could be happening there?

    • I do apologise. I had added the tracker to both the WP header and also to the single post body. Very stupid on my part :}

      Nice tutorial, very easy to follow.

  29. First of all thanks for this post. Second I have been using this script for a few days now and for some reason it started out fine and now it is not displaying the most viewed posts, I don’t see any rhyme or reason to what posts are now being displayed. The last I checked the post that it is displaying at the top has 8 page views. I know there are posts with 25+ recorded page views. I would like to figure this out. Can you possibly point me in the right direction. I followed this post word for word. The post views are being recorded properly.

  30. Hi. This works grade up until the view count gets over 999. All post with more view counts than 999 are not displayed, the query never post them. The latest post is the one with exactly 999 and the rest are under that. I have over 100 post that have more than thousand and are not being included.

  31. Guys you rockkk

    Quick question:
    If i have add a custom post type in your code ?
    (popular post from especific custom post type)

    Regards (:

  32. This is a good basic tutorial, but be warned: it’s not going to work if you use caching strategies that bypass PHP (like wp-supercache, W3TC, nginx/varnish, etc). The only way to count those would be via Javascript or log parsing.

    • Hey Artem, Thanks for dropping by. Actually using W3 Total Cache, you can use fragment caching and it works just fine. Going to update the article for those who are using the caching plugin.


      • Interesting. However, I run nginx in front of W3TC, and it does a whole lot of its own caching, so it’s always safer/more reliable to use an AJAX approach. Nice info on the fragment caching though, I had no idea W3TC had it.

  33. Why use
    //To keep the count accurate, lets get rid of prefetching
    remove_action( ‘wp_head’, ‘adjacent_posts_rel_link_wp_head’, 10, 0); ?

    if you can use the main loop or the footer ?

    • Some browsers prefetch the rel links with the next value. So technically when a user views one post, it can act as if they had viewed both posts. This will cause inaccurate count. If you like inflated views, then don’t take it off.


      • Please stop saying stuff like this. Plugins aren’t bad, it’s articles like this that make them look bad. Enough articles have come out over the past few weeks to fully explain this – it’s getting a little embarrassing.

        • How would you suggest titling future posts instead? DIY prefix? These are different then just using a pre-made plugin. Also, if you read the article, there is no where in our article that we say “plugins are bad”. We clearly state that the only reason why coded this was to get more customization. It is up to a user to take either stance. Some can think that plugins are bad… whereas others like yourself can think that we are saying that plugins are bad…

        • I don’t think any type of prefix is needed. It’s one of the great/scary things about WordPress. You COULD put this code in your theme, but then begs the argument about needing to either, 1) Loose those customizations when you change your theme, or 2) have the knowledge to properly pull those over to another theme.

          A lot of the users here are beginners (hence the point of this site), so many will just copy/paste what you give them. WP Beginner is obviously a fantastic resource (reason why I follow you on Twitter), but you have a responsibility to not put a false notion about how plugins/themes work.

          Correct, you don’t flat out say, “Plugins are bad, put this in your theme instead!”, but the original commenter to the thread I replied to, said, “Yay! A tutorial that doesn’t require a plugin!” – so even though you didn’t say it, that’s how it was taken.

          I’d suggest doing was Pippin does for his plugins – he has a simple starter plugin he uses for all of his tutorials. Why not create a blank “Starter Plugin” download, with just the basics, so others can download and put their customizations in there instead? Reference it in each article you do and it takes out some of the confusion. Thanks.

        • We have been following Otto’s advice on site-specific plugin for quite some time. It is probably similar to what Pippin does. If you read this article, site-specific plugin is hyperlinked. It is in most other articles as well. That article shows users the importance of site-specific plugin and advise users to not put everything in functions.php file. At the bottom of that article, the sample “starter plugin” is there for anyone to start with.

        • In fairness this tutorial helped me out. I wanted a simple solution for popular posts after trying some of the plugins and not being able to fully control the markup. This tutorial helped me quickly implement some popular posts functionality into my own plugin.

          So i agree that using pre-built plugins is not a bad thing, but at times tutorials like this are useful to take control and build out a plugin that works the way you need it to instead of fighting against an already built plugin.

    • As Zach said, please stop using “without a plugin”. Sure, it’s cool to see how to code this yourself but there is literally no difference between this code and the code in a plugin. You could place this code into a plugin and it would function identically to placing it in your theme.

      • If you say there’s no difference, you have no idea what you’re talking about. Lets say your are working on a site and don’t have access to the plugins directory, making a solution that works “without using a plugin” would be a viable alternative.

        As for the title, semantically the title should reflect the content of the post and could be “How to Display Popular Posts by Views in WordPress with or without a Plugin”.

        However, taking SEO in to consideration, lets say he would like this post to reach a specific audience, for example, people who don’t want to or can’t use a plugin, the title would probably be best as is.

  34. i am using genesis child theme..can u tell me which all functions and codes to use..i am sorry i am a noob to genesis…

      • is it true? as artim told, does this code become unresponsive when we use a caching plugin?? for example i currently use W3 total cache and i want to use this method to build my custom popular post by views widget…i read this kind of post on and the users suggested it does not work when we enable caching plugins…reply soon…

Leave a Reply to Sakshi Grover Cancel reply

Thanks for choosing to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published. Please Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.