Appearance
For Developers
Shortcode
The Elementor widget is a wrapper around one shortcode:
[voxel_review_badge post_id="123" style="compact"]| Attribute | Default | Purpose |
|---|---|---|
post_id | current post | The listing to show |
style | empty | One of compact, card, minimal, detailed, button. Empty renders every enabled style. |
custom_title | empty | Overrides the brand name on the badge |
review_override | empty | Forces a rating, 0–5. Suppresses structured data. |
anchor_text | empty | Overrides the anchor text template for this badge |
widget_id | empty | Identity used to keep an embed code stable across renders |
widget_id matters if you call the shortcode directly. The embed code's reference is derived from the widget type, this ID and the post ID, so a badge without one shares a reference with every other badge on the same listing. Elementor supplies its own widget ID automatically.
Filters
Changing the schema type
Every listing is described as a LocalBusiness. Map it to your own post types:
php
add_filter( 'voxel_embed_reviews_schema_type', function ( $type, $post_id ) {
switch ( get_post_type( $post_id ) ) {
case 'events': return 'Event';
case 'rentals': return 'LodgingBusiness';
case 'people': return 'Person';
}
return $type;
}, 10, 2 );Changing the whole structure
Add properties, or return null to publish nothing:
php
add_filter( 'voxel_embed_reviews_schema', function ( $schema, $post_id, $review_data ) {
$schema['address'] = [
'@type' => 'PostalAddress',
'streetAddress' => get_post_meta( $post_id, 'address', true ),
'addressLocality' => get_post_meta( $post_id, 'city', true ),
];
return $schema;
}, 10, 3 );Both run only where markup is published at all — see SEO & Structured Data.
Where the data comes from
Scores are read from Voxel's own voxel:review_stats post meta, a JSON blob holding total and average. Voxel stores its average on a −2 to +2 scale; the badge shifts it to the familiar 1–5 by adding 3, then clamps it.
Results are cached in a voxel_review_data_{post_id} transient for five minutes. Nothing needs invalidating — a new review appears on badges within that window.
If voxel:review_stats is missing, a handful of older meta keys are tried before the badge gives up and reports no reviews.
Endpoints
Both are admin-ajax.php actions, available to logged-out visitors, and both serve published, publicly viewable posts only.
| Action | Returns |
|---|---|
voxel_review_json | JSON for the badge. Requires a valid config reference. |
voxel_review_iframe | A standalone HTML page for the badge. Accepts config, or a bare post_id for older embeds. |
/wp-admin/admin-ajax.php?action=voxel_review_json&config=<hash>&style=compactThe JSON response carries the post URL and title, the review average and count, the branding settings, and the anchor text. It deliberately does not carry structured data.
voxel_review_iframe predates the JavaScript embed and is kept for badges embedded before it existed. New embed codes never use it.
Front-end JavaScript
The embed script exposes one method:
js
window.VoxelEmbedReviews.render();It renders any unclaimed .voxel-review-embed placeholder. The script also observes the DOM and calls this itself, so you only need it for cases a mutation observer cannot see.
Storage
| What | Where |
|---|---|
| Embed configurations | {prefix}voxel_widget_configs |
| Settings | voxel_embed_reviews_settings option |
| Schema version | voxel_embed_reviews_db_version option |
| Cached scores | voxel_review_data_* transients |
A daily voxel_cleanup_old_configs event removes configurations untouched for 30 days. A deleted configuration is recreated the next time its badge renders, so embed codes survive cleanup.
Uninstalling drops the table, the options and the cached scores, across every site on a multisite network. The license key is left in place so reinstalling does not mean re-entering it.

