Add Product Rich Snippets to WordPress Programmatically

To make structured product data such as prices or reviews as clear as possible for Google, it is wise to implement Google rich snippets on every product page on your website.

Google offers 3 ways to add structured data to your website. JSON-LD, RDFa and Microdata. I prefer JSON-LD because this is the first option in the list and you don’t have to touch any HTML, but only have to place a JSON data tree in the header of your website.

To add the JSON data to your WordPress website, use the wp_head action hook. This allows you to add scripts and elements between your <head> tags, the way WordPress wants to see it.

I created the JSON tree by first forming an array in PHP with the correct data according to the Google Product Rich Snippets documentation and then transforming this array into a JSON format with the json_encode() PHP function.

 * Adds json product data to head
function th_product_rich_snippets_head() {

   // Check is single product page
   if ( is_singular( 'product' ) ) {

      global $post;

      // Set right data according to documentation
      $json['@context']    = '';
      $json['@type']       = 'Product';
      $json['name']        = $post->post_title;
      $json['description'] = $post->post_excerpt;
      $json['mpn']         = $post->ID;
      $json['brand']       = [
         '@type' => 'Thing',
         'name'  => get_bloginfo( 'name' )

      // Stored review category in post meta
      if ( $review_category = get_post_meta( $post->ID, 'review_category', true ) ) {

         // Check for reviews from that category
         if ( $reviews = th_get_reviews( $number = -1, $review_category ) ) {

            foreach ( $reviews as $review ) {

               // Add a row per review
               $json['review'][] = [
                  '@type' => 'Review',
                  'reviewRating' => [
                     '@type' => 'Rating',
                     'ratingValue' => get_post_meta( $review->ID, 'rating', true ),
                     'bestRating' => 5,
                  'author' => [
                     '@type' => 'Person',
                     'name' => get_post_meta( $review->ID, 'name', true )

         // Add aggregate rating data through custom functions
         $json['aggregateRating'] = [
            '@type' => 'AggregateRating',
            'ratingValue' => th_get_review_average( false, $review_category ), // Custom function
            'reviewCount' => th_get_review_count( $review_category )  // Custom function

      // Product images stored in post meta
      if ( $gallery_images = get_post_meta( $post->ID, 'gallery_images', true ) ) {
         foreach ( $gallery_images as $image ) {
            $json['image'][] = $image['url'];

      // End script
      $output  = '<script type="application/ld+json">';

      // Encode to json format
      $output .= json_encode( $json, JSON_UNESCAPED_SLASHES );
      $output .= '</script>';

      echo $output;


add_action( 'wp_head', 'th_product_rich_snippets_head' );

Hold in mind..

As you can see I used a few custom functions such as th_get_review_average() and th_get_review_count() to provide the right review data. You can fill in yourself where you get the data from. The way I did it works as follows:

  • I created a post type for reviews.
  • Each review is attached to a review category.
  • I store the review category id in post meta of a product.
  • I load all the reviews from this category id into the JSON tree.

I hope my example will help you find out a way to implement this in your own website. Feel free to ask questions in the comments if you can’t figure it out. I would like to help!

Robbert Vermeulen

Need help from a WordPress expert?

I would love to hear about your project and how I can help you achieve your goals