Skip to main content

Goals reference

Goals let you measure conversions in Burst Statistics. Each goal tracks a specific user action — a click, a page visit, or a WordPress hook execution — and records how often it occurs relative to your chosen conversion metric.


Overview

A goal is stored as a row in {prefix}_burst_goals. When a visitor completes a goal, a record is written to {prefix}_burst_goal_statistics linking that pageview to the goal. Goals are represented by the Burst\Frontend\Goals\Goal class and managed in bulk via Burst\Frontend\Goals\Goals. Burst supports two processing paths:

  • Client-side — the browser tracking script detects the conversion (click or element view) and includes it in the tracking payload.
  • Server-side — PHP detects the conversion (a WordPress hook fires or a page is visited) and writes the statistic directly.

Pro - CreatorAvailable in the Creator tier

The Pro version allows unlimited goals. The free version permits only one goal at a time. If a goal already exists, Goal::save() silently returns false for any new insert on the free version. Learn more about goal conversion tracking


Goal types

Goal types are registered through the field definitions and can be extended with the burst_goal_types filter.

TypeTracking pathserver_sideDescription
clicksClient-sidefalseFires when a visitor clicks an element matching the configured CSS selector.
viewsClient-sidefalseFires when a visitor views an element matching the configured CSS selector.
visitsServer-sidetrueFires when a visitor lands on the target page.
hookServer-sidetrueFires when a specified WordPress action hook executes.

server_side is derived automatically in Goal::get():

$this->server_side = $this->type === 'hook' || $this->type === 'visits';

Configuration fields

These fields map directly to the goal editor in the admin UI.

title

FieldValue
Typehidden (set programmatically)
Defaultfalse (displays as "New goal" when empty)

The human-readable name shown in the goals list.


status

FieldValue
Typehidden (toggled via the goal editor UI)
Defaultfalse (inactive)
Accepted valuesactive, inactive

Controls whether the goal is currently collecting conversions. Setting status to active resets date_start to the current time.


type

FieldValue
Typeradio-buttons
Defaultclicks
Accepted valuesclicks, views, visits, hook

The type of event to track. See Goal types for details on each option.


page_or_website

FieldValue
Typeradio-buttons
Defaultwebsite
Accepted valuespage, website
Shown forclicks, views, hook goal types

Determines whether the goal applies to the entire site or only to a specific page.

OptionDescription
pageTrack only when the conversion happens on a specific page
websiteTrack the conversion anywhere on the site

When website is selected, the stored url value is set to *.


specific_page

FieldValue
Typeselect-page
Defaultfalse
Shown forvisits type, or when page_or_website is page

The specific page to track. Accepts a relative URL. When page_or_website is website, this field is ignored and url is stored as *.


selector

FieldValue
Typeselector
Default'' (empty string)
Shown forclicks and views goal types

A CSS selector identifying the element to track. For example: #newsletter-form .submit-btn or .add-to-cart.

The value is sanitized with sanitize_text_field() before storage.


hook

FieldValue
Typehook
Default'' (empty string)
Shown forhook goal type only

The WordPress action hook name to listen for. For example: woocommerce_payment_complete or my_plugin_form_submitted.

The value is sanitized with sanitize_text_field() before storage.

caution

Hook-type goals rely on the burst_uid cookie being set by a prior client-side pageview. If the hook fires before the visitor has been tracked (for example, during a server-side-only request), the conversion will not be recorded.


conversion_metric

FieldValue
Typeradio-buttons
Defaultvisitors
Accepted valuesvisitors, sessions, pageviews

Determines the denominator used when calculating the conversion rate.

OptionDescription
visitorsConversions ÷ unique visitors
sessionsConversions ÷ total sessions
pageviewsConversions ÷ total pageviews

Goal object

The Burst\Frontend\Goals\Goal class represents a single goal. Properties are read/write via magic __get / __set.

PropertyTypeDefaultDescription
idint0Database primary key (ID column).
titlestring''Human-readable goal name. Defaults to "New goal" when empty.
typestring'clicks'Goal type slug. See Goal types.
statusstring'inactive''active' or 'inactive'.
server_sideboolfalseSet automatically to true when type is 'hook' or 'visits'. Derived at load time — not stored as a separate column.
urlstring'*'Raw URL stored in the database. '*' means site-wide.
page_or_websitestring'website'Derived from url. 'website' when url === '*'; 'page' otherwise.
specific_pagestring''Relative URL used when page_or_website === 'page'. Derived from url.
conversion_metricstring'visitors'How conversions are counted.
selectorstring''CSS selector for clicks and views goal types.
hookstring''WordPress action name for hook goal type.
date_startintUnix timestamp when the goal became active. Reset each time status changes to 'active', or on first creation.
date_endint0Unix timestamp when tracking ended. 0 means still running.
date_createdint0Unix timestamp of first insertion.

Deprecated properties

caution

The following properties were deprecated in v2.0.0 and may be removed in a future release. Do not use them in new code.

PropertyTypeReplacement
attribute?stringUse selector instead
attribute_value?stringUse selector instead

Tracking lifecycle

Client-side goals (clicks, views)

  1. The visitor interacts with an element matching the goal's selector.
  2. The frontend goals script appends the goal ID to the completed_goals array in the tracking payload.
  3. The tracking endpoint receives the payload and records the conversion in {prefix}_burst_goal_statistics.

Server-side goals — hook type

  1. During the WordPress init action, Goals_Tracker::add_dynamic_hooks() reads every active hook-type goal and registers a WordPress action for each goal's hook property.
  2. When that action fires, Goals_Tracker::handle_hook( $hook_name ) runs:
    • Reads the burst_uid cookie to identify the visitor.
    • If no burst_uid is present, the conversion is not recorded.
    • Retrieves the visitor's most recent statistic row via get_last_user_statistic().
    • If the goal is scoped to a specific page (page_or_website === 'page'), checks that specific_page appears in the stored page_url + parameters string.
    • Calls create_goal_statistic() to write the conversion.
Show code
// Trigger a custom hook-type goal.
// 1. In Burst, create a goal with type = 'hook' and hook = 'my_plugin_form_submitted'.
// 2. Fire the action from your plugin:
do_action( 'my_plugin_form_submitted' );
// Goals_Tracker picks up the action and records the conversion
// for the currently identified visitor.

Server-side goals — visits type

Burst detects the target page URL server-side and records a conversion when the visitor lands on the matching URL.


Goal conversion queries

Internally, Goal_Statistics::get_goal_completed_count_sql() builds the SQL used to count goal completions. As of v3.3.0, this query JOINs {prefix}_burst_sessions so that session-level attributes such as device_id are read from the sessions table rather than the statistics table.

:::caution Breaking change

Changed in v3.3.0: device_id (and the related browser_id, platform_id, browser_version_id, first_time_visit, and bounce columns) have moved from {prefix}_burst_statistics to {prefix}_burst_sessions. Any custom SQL that queries goal conversions and references these columns by statistics.device_id (or without a table qualifier) must be updated to JOIN {prefix}_burst_sessions and reference sessions.device_id instead.

:::

The generated SQL now takes the following form:

Show code
// Simplified representation of the query produced by get_goal_completed_count_sql().
global $wpdb;

$sql = $wpdb->prepare(
"SELECT COUNT(DISTINCT statistics.uid) AS value
FROM {$wpdb->prefix}burst_statistics AS statistics
INNER JOIN {$wpdb->prefix}burst_goal_statistics AS goals
ON statistics.ID = goals.statistic_id
INNER JOIN {$wpdb->prefix}burst_sessions AS sessions
ON statistics.session_id = sessions.ID
WHERE goals.goal_id = %s
AND statistics.time > %s",
$goal_id,
$date_start
);

The device-breakdown query used to determine the best-performing device for a goal also references sessions.device_id:

Show code
// Pageviews per device — sessions JOIN required since device_id moved to burst_sessions.
$sql = $wpdb->prepare(
"SELECT COUNT(statistics.uid) AS value, sessions.device_id
FROM {$wpdb->prefix}burst_statistics AS statistics
INNER JOIN {$wpdb->prefix}burst_sessions AS sessions
ON statistics.session_id = sessions.ID
WHERE statistics.time > %s
GROUP BY sessions.device_id
ORDER BY value DESC
LIMIT 4",
$date_start
);

Database tables

TablePurpose
{prefix}_burst_goalsOne row per goal; stores all goal configuration.
{prefix}_burst_goal_statisticsMany-to-many join between statistic rows and goal IDs. All rows for a goal are deleted when the goal is deleted.

Tables are created via the burst_install_tables action. See burst_install_tables.


Predefined goals

Pro - CreatorAvailable in the Creator tier

Integrations can register predefined goal templates. These are surfaced in the goals UI when the corresponding third-party plugin is active. Learn more about goal conversion tracking

Goals::get_predefined_goals() collects goal templates from each registered integration and returns them as a flat list.

Show code
/**
* @param bool $skip_active_check Pass true to include goals from inactive integration plugins.
* @return array<int, array{
* id: string,
* type: string,
* description: string,
* status: string,
* server_side: bool,
* url: string,
* hook: string
* }>
*/
$predefined = burst_loader()->frontend->goals->get_predefined_goals();

By default only goals from active integration plugins are returned.

A predefined goal template can be saved with Goal::add_predefined( string $id ):

$goal = new \Burst\Frontend\Goals\Goal();
$new_id = $goal->add_predefined( 'woocommerce-purchase' );
// Returns the new goal ID on success, or 0 on failure.

add_predefined() sets status = 'active', conversion_metric = 'visitors', and url = '*' as defaults before calling save().

Available predefined goals by integration

IntegrationGoal IDTypeTrigger
Elementorelementor_pro_forms_form_submittedhookelementor_pro/forms/form_submitted
Elementorsubmit_button_clickclicks.elementor-field-type-submit .elementor-button
WooCommercewoocommerce_add_to_carthookwoocommerce_add_to_cart
WooCommercewoocommerce_checkout_order_createdhookwoocommerce_checkout_order_created
WooCommercewoocommerce_payment_completehookwoocommerce_payment_complete
WooCommercewoocommerce_add_to_cart_clickclicks.add_to_cart_button
WooCommercewoocommerce_click_checkout_buttonclicks.wc-block-cart__submit-button
Easy Digital Downloadsedd_complete_purchasehookedd_complete_purchase
Easy Digital Downloadsedd_add_to_cartclicks.edd-add-to-cart
Easy Digital Downloadsedd_go_to_checkoutclicks.edd_go_to_checkout
Easy Digital Downloadsedd_click_purchaseclicks#edd-purchase-button

Querying goals

Show code
$goals = burst_loader()->frontend->goals->get_goals( [
'status' => 'active', // 'active', 'inactive', or 'all' (default)
'limit' => 10, // default: 9999
'offset' => 0, // default: 0
'orderby' => 'ID', // any column in burst_goals; default: 'ID'
'order' => 'ASC', // 'ASC' or 'DESC'; default: 'ASC'
'date_start' => strtotime( '-30 days' ), // Unix timestamp; -1 = no filter (default)
'date_end' => time(), // Unix timestamp; default: time()
] );

foreach ( $goals as $goal ) {
echo $goal->id . ': ' . $goal->title . ' (' . $goal->type . ')';
}

date_start and date_end filter on date_created. The orderby value is validated against the actual columns of burst_goals; unknown values fall back to 'ID'.


Saving and deleting goals

Creating a new goal

Show code
$goal = new \Burst\Frontend\Goals\Goal();
$goal->title = 'Newsletter signup';
$goal->type = 'clicks';
$goal->selector = '#newsletter-form .submit-btn';
$goal->status = 'active';
$success = $goal->save();
echo $goal->id; // populated after a successful insert

Updating an existing goal

$goal = new \Burst\Frontend\Goals\Goal( 42 );
$goal->status = 'inactive';
$goal->save();

Deleting a goal

$goal = new \Burst\Frontend\Goals\Goal( 42 );
$goal->delete(); // removes the goal row AND all burst_goal_statistics rows for this goal

Save behaviour

  • title, selector, and hook are sanitized with sanitize_text_field().
  • url is sanitized as a relative URL. When page_or_website === 'website' the stored value is forced to '*'.
  • server_side is derived from the goal type definition — not settable by the caller.
  • date_start is set to time() on first creation or whenever status changes to 'active'.
  • Returns true on success, false on failure (including exceeding the free-tier goal limit).

REST API endpoints

All goals endpoints are under the burst/v1 namespace and require a valid nonce.

EndpointMethodPermissionDescription
burst/v1/goals/getGETviewReturns all configured goals and the list of predefined goals.
burst/v1/goals/addPOSTmanageCreates a new goal.
burst/v1/goals/setPOSTmanageUpdates an existing goal.
burst/v1/goals/deletePOSTmanageDeletes a goal and its associated statistics.
burst/v1/goals/add_predefinedPOSTmanageAdds a predefined goal from an integration.
burst/v1/data/goalsGETviewReturns goal conversion statistics for the selected date range.
burst/v1/data/live-goalsGETviewReturns live goal conversion counts (since midnight).

Permission levels:

  • view — requires view_burst_statistics capability
  • manage — requires manage_burst_statistics capability (typically administrators)

Hooks and filters

burst_goal_types

Filter the available goal type definitions. Controls which types appear in the goal editor and are accepted by Goal::save().

Parameters:

ParameterTypeDescription
$typesarrayAssociative array of goal type definitions keyed by type slug. Each entry may include label, description, icon, and server_side.

Example:

Show code
add_filter( 'burst_goal_types', function( array $types ): array {
$types['video_play'] = [
'label' => __( 'Video play', 'my-plugin' ),
'description' => __( 'Fires when a video starts playing.', 'my-plugin' ),
'server_side' => false,
];
return $types;
} );

burst_allowed_goal_types

Filters the normalized list of goal type slugs accepted by Burst's sanitization layer.

Use this alongside burst_goal_types when you introduce a custom type and want it to survive request validation.

Parameters:

ParameterTypeDescription
$goal_typesstring[]Allowed goal type slugs.

Example:

Show code
add_filter( 'burst_allowed_goal_types', function( array $goal_types ): array {
$goal_types[] = 'video_play';
return array_values( array_unique( $goal_types ) );
} );

burst_before_save_goals

Fires immediately before a goal is written to the database (both insert and update).

Parameters:

ParameterTypeDescription
$goal\Burst\Frontend\Goals\GoalThe Goal object about to be saved. Public properties can be read or mutated.

Example:

Show code
add_action( 'burst_before_save_goals', function( \Burst\Frontend\Goals\Goal $goal ): void {
if ( $goal->type === 'hook' && empty( $goal->hook ) ) {
$goal->hook = 'woocommerce_thankyou';
}
} );

burst_after_save_goals

Fires after a goal has been successfully saved and the object refreshed from the database. Does not fire when save() returns false.

Parameters:

ParameterTypeDescription
$goal\Burst\Frontend\Goals\GoalThe saved Goal object with current database values, including the new id for inserts.

Example:

Show code
add_action( 'burst_after_save_goals', function( \Burst\Frontend\Goals\Goal $goal ): void {
if ( $goal->status === 'active' ) {
my_crm_sync_goal( $goal->id, $goal->title );
}
} );

burst_install_tables

Action fired by the Burst installer to trigger database table creation. Goals hooks into this at priority 10 to create {prefix}_burst_goals.

Parameters: none.

Example:

// Force table creation, e.g. after a manual reset.
do_action( 'burst_install_tables' );

burst_goal_fields

Filters the goal-editor field schema used by the admin app.

Use this to alter the fields shown for goal creation/editing, including adding custom controls or removing unsupported ones.

Parameters:

ParameterTypeDescription
$fieldsarrayGoal field definitions loaded from goal-fields.php.

burst_after_updated_goals

Fires after goal collections are updated through the REST API, including add, update, and delete flows handled by the admin app.

This is broader than burst_after_save_goals, which fires per-goal on model save.

Parameters: none.

Example:

add_action( 'burst_after_updated_goals', function(): void {
my_plugin_refresh_goal_dependent_cache();
} );