Guide

Product page and assets

These hooks cover everything between the product page and the configurator opening: the Configure button, whether the configurator's scripts load at all, the configuration object handed to the browser, and the add-to-cart form inside the configurator.

See the hook reference index for how to register callbacks.

The Configure button

HookTypeArgumentsPurpose
mkl_pc_configure_buttonfilter$htmlThe button markup
mkl_pc_configure_button_a11y_descriptionfilter$html, $productThe screen-reader heading before it
get_configurator_element_attributesfilter$attributes, $productData attributes on the trigger element
mkl_configurator_button_data_attributesfilter$attributes, $productId, $attsSame, for the [mkl_configurator_button] shortcode
mkl_configurator_data_attributesfilter$attributes, $productId, $attsSame, for the inline [mkl_configurator] shortcode
configurator_convert_base_pricefilterfalse, $productWhether the base price is currency-converted client-side

Loading and assets

HookTypeArgumentsPurpose
load_configurator_on_pagefilter$loadWhether to load the configurator on this page
mkl_pc_scripts_product_page_beforeaction(none)Before the configurator's scripts are enqueued
mkl_pc_scripts_product_page_afteraction(none)After they are
mkl_pc_3d_viewer_enqueuedaction$productIdThe 3D viewer was enqueued for a 3D product, on its page or in a shortcode
mkl_pc/js/product_configurator/dependenciesfilter$depsDependencies of the main script
mkl_pc/js/configurator/dependenciesfilter$depsDependencies of the configurator view script
mkl_pc/css/product_configurator.cssfilter$stylesheetURL of the theme stylesheet
mkl_pc_3d_preload_urlsfilter$urls, $productIdModel URLs preloaded for 3D products

Configuration handed to the browser

HookTypeArgumentsPurpose
mkl_pc_js_configfilter$configThe config section of PC_config
mkl_pc_frontend_js_configfilter$argsThe whole of PC_config, last
mkl_pc_bg_imagefilter$urlDefault viewer background image
mkl_pc_show_formfilter$show, $postIdWhether the configurator renders a cart form
mkl_pc/reset_configurator_on_ajax_add_to_cartfilter$reset, $postIdReset after an AJAX add to cart
mkl_pc_do_not_override_imagesfilterfalseSkip re-resolving image URLs to the configured sizes
mkl_pc_get_saved_configuration_contentfilter$configurationA configuration being restored into the configurator
mkl_pc/current_user_can_view_order_configfilter$canViewWho may reload a configuration from an order

Price and cart form

HookTypeArgumentsPurpose
mkl_pc/get_product_pricefilter$price, $productThe base price the configurator prices from
mkl_pc/display_add_to_cart_buttonfiltertrue, $productWhether the form renders at all
mkl_pc/add_to_cart_button/default_labelfilter$labelThe label before third-party plugins adjust it
mkl_pc/add_to_cart_button/labelfilter$labelThe final label
mkl_pc/edit_item_in_cart_button/labelfilter$labelLabel when editing an existing cart item
mkl_pc/get_cart_iconfilter$svgThe cart icon markup
mkl_pc_frontend_configurator_cart_formaction(none)Inside the cart form
mkl_pc_frontend_configurator_after_add_to_cartaction(none)After the add-to-cart button
mkl_pc/sku_modefilter$mode, $productHow SKUs are displayed
mkl_pc/sku_labelfilter$html, $productThe SKU label markup
mkl_pc_configuration_price_shortcode_outputfilter$output, $price, $atts, $configIdOutput of the configuration price shortcode

load_configurator_on_page

The gate for every asset the configurator loads. By default it returns true when the product is configurable, or the post contains one of the configurator shortcodes, or the post has the mkl_load_configurator_on_page meta.

Return true to force the scripts onto a page where the shortcode is not detected — a page builder's template, a popup, a block your theme renders late:

php functions.php
add_filter( 'load_configurator_on_page', function ( $load ) {	return $load || is_page( 'design-studio' );} );
load_configurator_on_page.

This is the hook behind Forcing the configurator scripts to load. Returning true everywhere loads a substantial amount of JavaScript on every page — target it.

mkl_pc_configure_button

The whole Configure button. You get the assembled markup, including the data attributes the configurator needs to open.

php functions.php
add_filter( 'mkl_pc_configure_button', function ( $html ) {	return str_replace( 'configure-product ', 'configure-product my-class ', $html );} );
mkl_pc_configure_button.

Preserve the configure-product class and the data-… attributes, or the button stops opening the configurator. If you only need extra attributes, use get_configurator_element_attributes instead — it is far safer:

php functions.php
add_filter( 'get_configurator_element_attributes', function ( $attributes, $product ) {	$attributes['my_campaign'] = 'spring';	return $attributes;}, 10, 2 );
mkl_pc_configure_button.

Attribute names are printed as data-{name} and escaped for you. The same array already carries product_id, price, regular_price, is_on_sale and a settings sub-array.

See also Overriding the Configure button.

mkl_pc_js_config and mkl_pc_frontend_js_config

Two layers of the same object. mkl_pc_js_config filters the config section — the behaviour flags read all over the frontend. mkl_pc_frontend_js_config filters the complete PC_config object, including lang and config, and runs last.

php functions.php
// Force steps off for one product, whatever the setting says.add_filter( 'mkl_pc_js_config', function ( $config ) {	if ( 12345 === get_the_ID() ) {		$config['use_steps'] = false;	}	return $config;} );// Add your own data for your own scripts to read.add_filter( 'mkl_pc_frontend_js_config', function ( $args ) {	$args['my_plugin'] = array( 'endpoint' => rest_url( 'my/v1/quote' ) );	return $args;} );
mkl_pc_js_config and mkl_pc_frontend_js_config.

mkl_pc_frontend_js_config must return an array — anything else is replaced with an empty one, which breaks the configurator entirely.

mkl_pc/get_product_price

The base price the configurator starts from before any extra prices are added. It runs after the plugin's currency-conversion compatibility layers, so what you return is final.

php functions.php
add_filter( 'mkl_pc/get_product_price', function ( $price, $product ) {	return my_customer_specific_price( $price, $product );}, 10, 2 );
mkl_pc/get_product_price.

This changes the price the customer sees while configuring. The price actually charged comes from WooCommerce, so pair this with a cart hook or the two will disagree.

mkl_pc/display_add_to_cart_button

Return false and the configurator renders no cart form at all — the pattern for a catalogue-mode or quote-only configurator.

php functions.php
add_filter( 'mkl_pc/display_add_to_cart_button', function ( $display, $product ) {	return $product->get_price() ? $display : false;}, 10, 2 );
mkl_pc/display_add_to_cart_button.

mkl_pc/add_to_cart_button/label and …/default_label

default_label filters "Add to cart" before the plugin's quote-plugin compatibility runs; label filters the result. Use label unless you specifically need to run first.

php functions.php
add_filter( 'mkl_pc/add_to_cart_button/label', function ( $label ) {	return __( 'Order this configuration', 'my-plugin' );} );
mkl_pc/add_to_cart_button/label and …/default_label.

mkl_pc_frontend_configurator_cart_form and …_after_add_to_cart

Both print into the configurator's footer form, which is Underscore template markup — see Template hooks are different.

php functions.php
add_action( 'mkl_pc_frontend_configurator_cart_form', function () { ?>	<label class="gift-wrap">		<input type="checkbox" name="gift_wrap" value="1"> <?php esc_html_e( 'Gift wrap', 'my-plugin' ); ?>	</label><?php } );
mkl_pc_frontend_configurator_cart_form and …_after_add_to_cart.

Fields added here are inside the real form, so they post with the add-to-cart request.

mkl_pc/current_user_can_view_order_config

Guards reloading a configuration out of an order item — the "edit this configuration" flow from My Account. The default allows shop managers and the order's own customer.

php functions.php
add_filter( 'mkl_pc/current_user_can_view_order_config', function ( $can_view ) {	return $can_view;} );
mkl_pc/current_user_can_view_order_config.

The default is already correct for almost every store. Widening it exposes one customer's configuration to another.

mkl_pc_get_saved_configuration_content

The configuration about to be loaded into the configurator, whether it came from a cart item, an order, or a saved design. Return an empty array to load nothing.

php functions.php
add_filter( 'mkl_pc_get_saved_configuration_content', function ( $configuration ) {	return $configuration;} );
mkl_pc_get_saved_configuration_content.

mkl_pc/js/product_configurator/dependencies and mkl_pc/js/configurator/dependencies

Add script handles the configurator must wait for. The second defaults to jquery, backbone, wp-util, wp-hooks.

php functions.php
add_filter( 'mkl_pc/js/configurator/dependencies', function ( $deps ) {	$deps[] = 'my-plugin-configurator-extensions';	return $deps;} );
mkl_pc/js/product_configurator/dependencies and mkl_pc/js/configurator/dependencies.

This is only needed when your script must run before the configurator boots. For ordinary hook callbacks, depending on wp-hooks alone is enough and works on every page.

mkl_pc/css/product_configurator.css

The URL of the active theme's stylesheet, before it is registered as mlk_pc/css. Point it at your own file to replace the configurator's styling wholesale — though a child theme or extra stylesheet is usually a better idea.

mkl_pc_scripts_product_page_before and _after

Bracket the configurator's own enqueues, which is what makes them useful for ordering: register on _before if the configurator must depend on you, on _after if you must load later.

php functions.php
add_action( 'mkl_pc_scripts_product_page_after', function () {	wp_enqueue_script( 'my-plugin-after', '…', array( 'mkl_pc/js/product_configurator' ), '1.0', true );} );
mkl_pc_scripts_product_page_before and _after.

mkl_pc_3d_viewer_enqueued

Fires when the 3D viewer script is enqueued for a 3D product: on the product's own page, and for each 3D product a [mkl_configurator] or [mkl_configurator_button] shortcode shows on any other page. It fires once per product and request, with the parent product ID.

This is the place to enqueue scripts that extend the 3D viewer. Use the ID it gives you rather than the global $post: on a shortcode page, the global post is the page, not the product. On the product page it fires just before mkl_pc_scripts_product_page_after; for a shortcode it fires while the content renders, so enqueue in the footer.

php functions.php
add_action( 'mkl_pc_3d_viewer_enqueued', function ( $product_id ) {	if ( ! get_post_meta( $product_id, '_my_3d_feature', true ) ) {		return;	}	wp_enqueue_script( 'my-3d-addon', '…', array( 'mkl_pc/fe_3d_viewer' ), '1.0', true );} );
mkl_pc_3d_viewer_enqueued.

mkl_pc_3d_preload_urls

The glTF model URLs emitted as <link rel="preload"> in the head of a 3D product page. Filter it to drop a model that is rarely used, or to add one you load yourself.

php functions.php
add_filter( 'mkl_pc_3d_preload_urls', function ( $urls, $product_id ) {	return array_slice( $urls, 0, 1 ); // preload only the first model}, 10, 2 );
mkl_pc_3d_preload_urls.

mkl_pc/sku_mode and mkl_pc/sku_label

sku_mode is 'individual' by default, printing each choice's SKU beside it in cart and order meta. sku_label is the markup before the value.

php functions.php
add_filter( 'mkl_pc/sku_mode', function ( $mode, $product ) {	return 'none';}, 10, 2 );
mkl_pc/sku_mode and mkl_pc/sku_label.

Note that mkl_pc/sku_mode is applied in two places, only one of which passes $product — guard against it being absent.

mkl_pc_do_not_override_images

The configurator normally re-resolves every image URL to the sizes chosen in its settings. Return true to leave the stored URLs alone — useful when a CDN or an image optimiser has already rewritten them.

mkl_pc_configuration_price_shortcode_output

The rendered output of the configuration price shortcode, with the raw price, the shortcode attributes and the configuration id alongside it.

php functions.php
add_filter( 'mkl_pc_configuration_price_shortcode_output', function ( $output, $price, $atts, $config_id ) {	return '<span class="from">' . esc_html__( 'from', 'my-plugin' ) . '</span> ' . $output;}, 10, 4 );
mkl_pc_configuration_price_shortcode_output.

Compatibility filters

configurator_convert_base_price, wc_aelia_cs_get_product_price and woocommerce_product_price_class exist for multi-currency plugins and themes. The first decides whether the browser converts the base price itself; the other two are third-party hooks the plugin fires so existing customisations keep working.