How to exclude visited posts from loop

This is a heavier question than you think. You’ll need to do quite a bit:

  1. Set a cookie in the user’s browser to keep track of the posts they’ve seen.
  2. Pull data out of that cookie to get a list of post IDs
  3. Add this to the array with the $featured_post_id to pass it in the post__not_in parameter

I won’t deal with the first two issues … setting and reading cookies isn’t a WordPress question and you can easily find that information with a simple Google search.

But for the rest of it, your code will look something like this:

// get_previously_viewed_posts() will retrieve a list of viewed post IDs from a user cookie.
$posts_to_exclude = get_previously_viewed_posts();

// Add the current post ID to the array of posts to ignore.
$posts_to_exclude[] = get_the_ID();

$args = array(
    'cat'            => '9', 
    'posts_per_page' => 5, 
    'post__not_in'   => $posts_to_exclude
);

$my_query = new WP_Query( $args );

if ( $my_query->have_posts() ) : while ( $my-query->have_posts() ) : $my-query->the_post();

    // the loop

endwhile; endif;