How to use the pre_get_posts() function in WordPress

The flexibility with which WordPress can manage posts and pages is one of the platform’s most valuable features. The pre_get_posts() function allows you to adjust the way that WordPress shows posts, which is one of the scenarios in which you would wish to make such a change. In this article, we will discuss why it is preferable to utilise the pre_get_posts() method in WordPress rather than directly manipulating the WordPress loop, as well as how to use the pre_get_posts() function.

What is the pre_get_posts() function in WordPress?

The pre_get_posts() function is a WordPress filter that allows you to modify the query that retrieves posts from the database. This function is called before the main WordPress query runs, which means you can alter the query parameters before WordPress retrieves the posts.

How to use the pre_get_posts() function in WordPress?

To use the pre_get_posts() function, you need to add a filter to your WordPress theme’s functions.php file, child theme’s functions.php file or a custom plugin. Here’s an example of how to modify the query to show only posts with the ‘featured’ category:

function custom_featured_posts( $query ) {
    if ( ! is_admin() && $query->is_main_query() && is_home() ) {
        $query->set( 'category_name', 'featured' );
add_action( 'pre_get_posts', 'custom_featured_posts' );

In this example, the function checks whether the query is the main query on the home page and not in the admin panel. If these conditions are true, it modifies the query to show only posts with the ‘featured’ category.

The above example is very simple, but pre_get_posts() can also be used to create complex queries such as:

function custom_filter_posts( $query ) {
    if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'products' ) ) {

        // Filter by taxonomy terms
        $tax_query = array(
            'relation' => 'AND',
                'taxonomy' => 'product_category',
                'field'    => 'slug',
                'terms'    => array( 'clothing', 'accessories' ),
                'operator' => 'IN',
                'taxonomy' => 'product_tag',
                'field'    => 'slug',
                'terms'    => array( 'sale', 'new-arrival' ),
                'operator' => 'IN',
        $query->set( 'tax_query', $tax_query );

        // Filter by custom fields
        $meta_query = array(
            'relation' => 'AND',
                'key'     => 'product_color',
                'value'   => 'red',
                'compare' => '=',
                'key'     => 'product_price',
                'value'   => 50,
                'type'    => 'numeric',
                'compare' => '<=',
        $query->set( 'meta_query', $meta_query );

        // Set orderby and order parameters
        $query->set( 'orderby', 'date' );
        $query->set( 'order', 'DESC' );
add_action( 'pre_get_posts', 'custom_filter_posts' );

In this particular instance, the function examines the query to determine whether or not it is the primary query for the goods post type archive page. If this condition is met, then the query is altered to filter articles according to a combination of different taxonomies and user-defined fields. The tax query option narrows the search for postings to those that include either the ‘clothing’ or ‘accessories’ category as well as either the’sale’ or ‘new-arrival’ tag. Posts are filtered out by the meta query parameter if they have a product color custom field value of’red’ and a product price custom field value that is either less than or equal to 50. At the end, the function sorts the posts in descending order based on the date, which it determines by setting the orderby and order arguments.

This example highlights how powerful and versatile the pre_get_posts() function can be, since it enables you to filter posts based on many criteria and adjust the ordering of the results. You can view the full example here.

Advantages of using pre_get_posts() instead of modifying the WordPress loop


The pre_get_posts() function allows you to modify the query before WordPress retrieves the posts from the database. This implies that you may enhance speed while conserving resources by only fetching the posts that are absolutely essential.

Separation of Concerns

Changing the WordPress loop directly might make your code more difficult to maintain and debug, thanks to the separation of concerns principle. Your code will be much simpler to maintain and troubleshoot thanks to the pre_get_posts() function, which divides the logic for doing queries from the logic for displaying those results.


Modifying the query parameters in a dynamic manner in response to a wide variety of situations is made possible by the pre_get_posts() function’s flexibility. You are able to customise the query in many different ways, such as basing it on the role of the user, the current date, or the kind of post.

No modification needed to plugin CPT’s

If a plugin adds a custom post type, for example WooCommerce adds “products”, you can modify the product output using pre_get_posts() without having to touch any of the core WooCommerce code. This means your custom query will survive updates to the underlying plugin.


You have the ability to adjust the query that is used to obtain posts from the database by utilising a sophisticated WordPress filter known as the pre_get_posts() function. Using this function will allow you to increase the flexibility of your code, improve the efficiency of your website by separating the query logic from the display logic, and enhance the performance of your website. You now have enough information, in the form of examples and benefits, to begin utilising the pre_get_posts() function in your very own WordPress development projects.