Statamic 6 addon that syncs product reviews from Yotpo into a local collection. Reviews stay on your server (no client-side Yotpo widgets), are editable in the Control Panel, and render with Antlers plus Schema.org JSON-LD.
Provider today: Yotpo. Architecture supports additional platforms later.
Features
- Pull Yotpo reviews via REST API into a
product_reviewscollection - Automatic CDN fallback when the Core API times out
- Scheduled and on-demand sync (down to every five minutes)
- Manual override so CP edits are not overwritten
- Antlers tags for listing, averages, and counts
- Drop-in Antlers partial with star rating, schema, photos, and pagination
- Schema.org Product / AggregateRating / Review markup
- CP utility for connection test, status, and “Sync now”
Requirements
- PHP 8.3+
- Statamic 6
- A Yotpo account with App Key + API Secret
Install
composer require brainjuredstudio/product-reviewsphp artisan vendor:publish --tag=product-reviews-configphp artisan vendor:publish --tag=product-reviews-contentphp artisan vendor:publish --tag=product-reviews-partials
On php please statamic:install, config and content publish automatically.
Configure
Add to .env:
PRODUCT_REVIEWS_YOTPO_APP_KEY=your-app-keyPRODUCT_REVIEWS_YOTPO_SECRET=your-api-secret
Optional:
PRODUCT_REVIEWS_PROVIDER=yotpoPRODUCT_REVIEWS_PAGE_SIZE=100PRODUCT_REVIEWS_SCHEDULE=hourlyPRODUCT_REVIEWS_YOTPO_SOURCE=autoPRODUCT_REVIEWS_YOTPO_PRODUCT_IDS=sku-123,sku-456PRODUCT_REVIEWS_YOTPO_INCLUDE_SITE_REVIEWS=truePRODUCT_REVIEWS_YOTPO_TIMEOUT=60PRODUCT_REVIEWS_YOTPO_CONNECT_TIMEOUT=15
| Variable | Values | Default |
|---|---|---|
PRODUCT_REVIEWS_SCHEDULE |
daily, twice_daily, hourly, every_thirty_minutes, every_fifteen_minutes, every_five_minutes |
daily |
PRODUCT_REVIEWS_YOTPO_SOURCE |
auto (Core then CDN), core, cdn |
auto |
PRODUCT_REVIEWS_YOTPO_PRODUCT_IDS |
Comma-separated storefront product IDs / SKUs for CDN sync | (empty) |
Yotpo credentials: Settings → Store Settings → API Credentials.
Product ID matching
product_id on synced entries must match the ID you use in Antlers — typically your storefront SKU / external product ID (Shopify product/variant ID or SKU), not Yotpo’s internal numeric ID.
{{ product_reviews product_id="{{ sku }}" }}
If Core API syncs fine, SKUs usually land correctly. For CDN-only or CDN fallback syncs, set:
PRODUCT_REVIEWS_YOTPO_PRODUCT_IDS=your-sku-1,your-sku-2
Those values should be the same IDs Yotpo knows as the product’s domain_key / external ID. After the first sync, existing entry product_id values are reused automatically on later CDN runs.
If reviews sync but the frontend shows zero, compare Collections → Product Reviews → product_id with the product_id= value in your template.
Sync
php please product-reviews:sync# orphp artisan product-reviews:sync
Or Utilities → Product Reviews → Sync Now in the Control Panel. Use Test Connection to verify credentials without a full sync. Sync runs in the background queue so the CP does not time out on slow Yotpo responses.
Default schedule is daily. Ensure the host runs Laravel’s scheduler and a queue worker when using CP sync:
* * * * * cd /path/to/site && php artisan schedule:run >> /dev/null 2>&1
php artisan queue:work
Drop-in partial
Publish the partial once:
php artisan vendor:publish --tag=product-reviews-partials
Then on any product template:
{{ partial:product-reviews/list product_id="{{ sku }}" product_name="{{ title }}" limit="10" page="{get:page}" }}
Hide the built-in rating header when your product page already shows one:
{{ partial:product-reviews/list product_id="{{ sku }}" show_header="false" }}
The partial outputs Schema.org JSON-LD, star rating summary, review list (with photos when synced), and prev/next pagination links. Override styles via the .product-reviews classes or copy the partial into your theme.
Antlers
{{ product_reviews:schema product_id="sku-123" product_name="Product Name" }} <p> {{ product_reviews:average product_id="sku-123" }}/5 ({{ product_reviews:count product_id="sku-123" }} reviews)</p> {{ product_reviews product_id="sku-123" limit="10" }} <article> <strong>{{ rating }}/5</strong> — {{ author_name }} <h3>{{ title }}</h3> <p>{{ body }}</p> </article>{{ /product_reviews }}
Parameters: product_id, min_rating, provider, limit, page, offset, sort (default reviewed_at:desc).
Pagination: page is 1-based and works with limit. Use offset for explicit skipping (offset wins when both are set).
Moderation
Collections → Product Reviews
- Unpublish to hide on the frontend
- Enable Manual Override before editing so the next sync won’t overwrite your changes
License
Commercial / proprietary. A valid Statamic Marketplace license is required per site. See LICENSE.md.
Support
Email: [email protected]
Changelog
See CHANGELOG.md.