pagination for a custom loop with multiple post types

For altering the main query, the preferred method is to use the pre_get_posts action rather than calling query_posts in the template. It’s fairly safe to say at this point that any use of query_posts in the template is simply wrong, though sadly you will see a million examples of it all over the web.

The main query happens before the template is loaded, and WordPress makes the decision about what to do based on the result of that query, so doing things with the query in the template is going to be fraught with potential error. It’s also a waste of resources to run a second query that overwrites the original, best to alter the query before it happens.

So here we use the conditional tags to check if we’re on the front page and running the main query. It’s important to note that this action is executed on every query, so we have to be explicit about which one we want to alter.

function wpa_post_types_front_page( $query ) {
    if ( $query->is_front_page() && $query->is_main_query() ) {
        $query->set( 'post_type', array(
            'post',
            'product',
            'flights',
            'touristdestinations'
        ) );
    }
}
add_action( 'pre_get_posts', 'wpa_post_types_front_page' );

Now WordPress will query all of your post types, it will know what page it’s on, and how many pages exist, so pagination functions in the template should just work without having to do anything further.