← Back to blog

How to Add a Review System to a React Ecommerce Site

Most headless ecommerce builds leave reviews as an afterthought. This guide walks you through adding a full review and rating system to any React store — from JS snippet to live Google rich snippets.

If you're building a headless or custom React ecommerce store, product reviews are often the last thing you think about — and the first thing your customers notice is missing. A 4.8 ★ rating next to a product name builds trust instantly. The absence of any rating raises suspicion.

This guide walks through adding a complete review and rating system to a React or Next.js ecommerce site using Growbic Reviews. By the end, you'll have:

  • A working star rating widget on your product pages
  • Automated post-purchase review request emails
  • JSON-LD schema so ratings appear in Google search results
  • SSR-compatible review fetching via the REST API

Why not just use a platform's built-in reviews?

If you're on a headless setup — Next.js fronted by Shopify, a custom backend, or anything that isn't a traditional theme — platform-native reviews often don't port over cleanly. Shopify's review widget is tied to their Liquid templates. WooCommerce's reviews are PHP-rendered. SFCC has no native review system at all.

A dedicated review API is the right call for any headless or custom React ecommerce site. You get full control over rendering, SSR support, and a consistent review experience regardless of what's powering the backend.

Step 1: Add the JS snippet

The quickest way to get started is with our JS snippet. Add it to your HTML or inject it in your React app's entry point:

<!-- Add to your product page template -->
<script
  src="https://cdn.growbic.com/reviews/v1/widget.js"
  data-store-id="YOUR_STORE_ID"
  async
></script>

<!-- Place this where you want reviews to appear -->
<div
  class="growbic-reviews"
  data-product-id="PRODUCT_ID"
></div>

Step 2: Fetch reviews server-side for SEO

For Next.js, fetch review summary data server-side so the page HTML includes the review count and average. This powers your Google rich snippets.

// pages/products/[id].jsx

export async function getStaticProps({ params }) {
  const [product, reviewSummary] = await Promise.all([
    fetchProduct(params.id),
    fetch(
      `https://api.growbic.com/reviews/summary?productId=${params.id}`,
      { headers: { 'X-Store-ID': process.env.GROWBIC_STORE_ID } }
    ).then(r => r.json())
  ])

  return {
    props: { product, reviewSummary },
    revalidate: 60
  }
}

Step 3: Add JSON-LD for Google rich snippets

Use the review summary to render a JSON-LD block in your page head. This makes your star ratings appear directly in Google search results.

import Head from 'next/head'

function ProductJsonLd({ product, reviewSummary }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "Product",
    "name": product.name,
    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": reviewSummary.averageRating,
      "reviewCount": reviewSummary.totalReviews,
      "bestRating": "5",
      "worstRating": "1"
    }
  }

  return (
    <Head>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
      />
    </Head>
  )
}

Step 4: Trigger review requests after purchase

Call the Growbic API from your backend when an order is fulfilled:

// api/order-fulfilled.js

export default async function handler(req, res) {
  const { orderId, customerEmail, products } = req.body

  await fetch('https://api.growbic.com/reviews/request', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Store-ID': process.env.GROWBIC_STORE_ID,
      'X-API-Key': process.env.GROWBIC_API_KEY,
    },
    body: JSON.stringify({
      orderId,
      customerEmail,
      products: products.map(p => ({ id: p.id, name: p.name })),
      sendAfterDays: 7
    })
  })

  res.status(200).json({ ok: true })
}

Need help with the setup? Reach out to the Growbic team — we'll walk you through it.