Often, when I’m working on content sites, one of my initial product goals is to increase session depth. Broadly, this means decreasing bounce rates and have visitors read more than one article. 

Large publishers often call this content recirculation, but their goals are to take visits and push them into higher-value pages for revenue purposes. 

Since it’s a blog without any monetization, my goal on this website is to push visitors into other content and hopefully earn an email opt-in. My stats show me that readers are more likely to join my newsletter when they read multiple posts. 

Content Sequencing for Session Depth

People need to be interested in something to click on it. 

To make this happen, my gut says that I’m better served by giving the user more of what they’re already here for instead of showing them something random. 

It’s helpful to think of your content in terms of a sequence — which articles are most relevant to users at which times? 

Some content should be consumed in a linear sequence, such as tutorials with multiple parts. It would be a mistake to recommend content out of sequence. 

Other posts are standalone and can be consumed in any order, but users may still have a preference for when they’re shown. 

For example, you probably don’t care about the depth year that I took in 2020 unless you’re familiar with me as a person. Most first-time visitors would be better served being recommended pretty much anything else. 

By default, I’d like to show them closely related articles. 

WordPress has two handy built-in taxonomies that help group content. 

Categories vs. Tags 

The internet is filled with debates about which is better — but I don’t dig too deep into information hierarchy. 

I’ve got a quick rule that I heard somewhere a long time ago. 

Categories are the table of contents, and tags are the index.

Following this logic, I use categories for major site sections: 

  • Blog Posts 
  • Marketing Patterns 
  • Conversion Gold

I use tags to help create groups of content. 

I have tags for: 

  • Reviews 
  • Productivity
  • Design
  • Site updates

The idea is to use these tags to group similar content to show a user. 

If you’re reading my Focusmate review, there are two groups of content that I think would be interesting to you: 

  • Other reviews (FMail, Things 3)
  • Content related to the product niche (Productivity)

If you had many reviews, the best ones to show would be the ones that were tagged with both Productivity and Reviews. 

So let’s build it. 

Code Example

To restate the problem and define the solution: 

The use case for this feature will be to upgrade a quick visit to a session with more depth. I want the user to read the post they landed on and see something else that catches their eye. In theoretical terms, I’m trying to bridge the specific information they came for with a broader topic that they can explore. 

I want to add a “you might also like” section to the end of each post. In WordPress, this file is single.php.

We have to grab the tags from the current post and run a query on the posts database to find five random posts that have one or more of the tags from the current post. 

Oh, and since there may be more than five posts to recommend, and we’re unsure which are the best to show users, we’ll randomize the list. 

Here is the important part broken out, with comments 

$args = array(
  'tag__in' => $tag_ids, //makes sure the tag is present
  'post__not_in' => array($post->ID), //makes sure we do not recommend the current post
  'orderby' => 'rand', //gives us a random group
  'posts_per_page' => 5 //shows 5 related posts
);

Here’s the full snippet to display the related posts by tag: 

<div style="padding-bottom:20px;">
  <h3>You might also like:</h3>
  <?php $orig_post = $post;
  global $post;
  $tags = wp_get_post_tags($post->ID);
  if ($tags) {
    $tag_ids = array();
    foreach($tags as $individual_tag) $tag_ids[] = $individual_tag->term_id;
    $args = array(
      'tag__in' => $tag_ids,
      'post__not_in' => array($post->ID),
      'orderby' => 'rand',
      'posts_per_page' => 5
    );
    $my_query = new wp_query( $args );
    if( $my_query->have_posts() ) {
      echo '<ul>';
      while( $my_query->have_posts() ) {
        $my_query->the_post(); ?>
        <li><a href="<?php the_permalink()?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></li>
        <?php }
       echo '</ul>';
      }
    }
  $post = $orig_post;
  wp_reset_query(); ?>
</div>