Skip to content

For Developers

Shortcode

The Elementor widget is a wrapper around one shortcode:

[voxel_review_badge post_id="123" style="compact"]
AttributeDefaultPurpose
post_idcurrent postThe listing to show
styleemptyOne of compact, card, minimal, detailed, button. Empty renders every enabled style.
custom_titleemptyOverrides the brand name on the badge
review_overrideemptyForces a rating, 0–5. Suppresses structured data.
anchor_textemptyOverrides the anchor text template for this badge
widget_idemptyIdentity 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.

ActionReturns
voxel_review_jsonJSON for the badge. Requires a valid config reference.
voxel_review_iframeA 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=compact

The 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

WhatWhere
Embed configurations{prefix}voxel_widget_configs
Settingsvoxel_embed_reviews_settings option
Schema versionvoxel_embed_reviews_db_version option
Cached scoresvoxel_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.

Built by Code Wattz.