Getting to Know Woo: Modifying existing Cart and Checkout Block Fields

Co-written by @ralucastn and @nielslange


In the previous installment of this series we looked at how we could customize the content of the Cart and Checkout blocks. Now, we are going to see how we can customize existing fields using the Filter registry, which is similar to the traditional filter system in WordPress.

Modifying existing Cart and Checkout Block Fields

Checkout JS filters

We have implemented a Filter registry that allows callbacks to be registered to manipulate certain values in the Cart and Checkout blocks. This is similar to the traditional filter system in WordPress, where you register a callback with a specific filter and return a modified value.

We offer a variety of filters to extend the way certain strings are displayed.

Available Filters

All code snippets below can be added to a test site using the plugin Simple Custom CSS and JS. To ensure that

  const { registerCheckoutFilters } = window.wc.blocksCheckout;

loaded correctly, the code snippet needs to be placed in the <footer> element.

@woocommerce/blocks-checkout is defined in Webpack to point to window.wc.blocksCheckout. If needed, this can be adjusted in the build tools of a custom extension.

Apart from the dependencies, some of the following snippets refer to a certain context. Here’s an example of one of the filters:

// Return early since this filter is not being applied in the Cart context.
// We must return the original value we received here.
if ( args?.context !== 'cart' ) {
    return value;
}

args?.context can have one of the following values:

  • cart
  • summary

Additional Cart Checkout inner block types

The additionalCartCheckoutInnerBlockTypes filter allows to add additional inner block types.

The following code snippet shows how to use the additionalCartCheckoutInnerBlockTypes filter:

document.addEventListener('DOMContentLoaded', function() {
	const { registerCheckoutFilters } = window.wc.blocksCheckout;

	// Adjust allowed cart and checkout inner block types.
	registerCheckoutFilters( 'example-extension', {
	  additionalCartCheckoutInnerBlockTypes: ( value, extensions, args ) => {
		// Remove the ability to add `core/separator`
		value = value.filter( ( blockName ) => blockName !== 'core/separator' );

		// Add core/quote to any inner block area.
		value.push( 'core/quote' );

		// If the block we're checking is `woocommerce/checkout-shipping-address-block then allow `core/table`.
		if ( args?.block === 'woocommerce/checkout-shipping-address-block' ) {
		  value.push( 'core/table' );
		}

		return value;
	  }
	} );
} );

Cart Line Items » cartItemClass

The cartItemClass filter allows adding a custom class to the cart line items.

The following code snippet shows how to use the cartItemClass filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust cart item class of the cart line items.
registerCheckoutFilters( 'example-extension', {
  cartItemClass: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return 'my-custom-class';
  }
} );

Cart Line Items » cartItemPrice

The cartItemPrice filter allows adding an additional text to the cart line items.

The following code snippet shows how to use the cartItemPrice filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust cart item price of the cart line items.
registerCheckoutFilters( 'example-extension', {
  cartItemPrice: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return '<price/> for all items';
  }
} );

Cart Line Items » subtotalPriceFormat

The subtotalPriceFormat filter allows enhancing the product name of the cart line items.

The following code snippet shows how to use the subtotalPriceFormat filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;
 
// Adjust subtotal price format of the cart line items.
registerCheckoutFilters( 'example-extension', {
  subtotalPriceFormat: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return '<price/> per item';
  }
} );

Cart Line Items » itemName

The itemName filter allows enhancing the product name of the cart line items.

The following code snippet shows how to use the itemName filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust item name of the cart line items.
registerCheckoutFilters( 'example-extension', {
  itemName: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return '🪴 ' + value + ' 🪴';
  }
} );

Cart Line Items » saleBadgePriceFormat

The saleBadgePriceFormat filter allows adding an additional text to the sales badge of the cart line items.

The following code snippet shows how to use the saleBadgePriceFormat filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust sale badge price format of the cart line items.
registerCheckoutFilters( 'example-extension', {
  saleBadgePriceFormat: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return '<price/> per item';
  }
} );

Cart Line Items » showRemoveItemLink

The showRemoveItemLink filter allows hiding the remove item link of the cart line items.

The following code snippet shows how to use the showRemoveItemLink filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Show remove item link of the cart line items.
registerCheckoutFilters( 'example-extension', {
  showRemoveItemLink: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Cart context.
    // We must return the original value we received here.
    if ( args?.context !== 'cart' ) {
      return value;
    }
    return false;
  }
} );

Coupons

The coupons filter allows to show, hide and change the coupon display name.

Before After

The following code snippet shows how to use the coupons filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Replace coupon label for matching coupon(s).
registerCheckoutFilters( 'example-extension', {
	coupons: ( coupons ) => {
		return coupons.map( ( coupon ) => {
			// Regex to match autocoupon then unlimited undersores and numbers
			if ( ! coupon.label.match( /autocoupon(?:_d+)+/ ) ) {
				return coupon;
			}
			return {
				...coupon,
				label: 'Automatic coupon',
			};
		} );
	}
} );

Order Summary Items » subtotalPriceFormat

The subtotalPriceFormat filter allows adding an additional text to the subtotal of the order summary items.

The following code snippet shows how to use the subtotalPriceFormat filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust subtotal price format of the order summary items.
registerCheckoutFilters( 'example-extension', {
  subtotalPriceFormat: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Summary context.
    // We must return the original value we received here.
    if ( args?.context !== 'summary' ) {
      return value;
    }
    return '<price/> per item';
  }
} );

Order Summary Items » itemName

The itemName filter allows enhancing the product name of the order summary items.

The following code snippet shows how to use the itemName filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust item name of the order summary items.
registerCheckoutFilters( 'example-extension', {
  itemName: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Summary context.
    // We must return the original value we received here.
    if ( args?.context !== 'summary' ) {
      return value;
    }
    return '🪴 ' + value + ' 🪴';
  }
} );

Order Summary Items » cartItemPrice

The cartItemPrice filter allows adding an additional text to the order summary items.

The following code snippet shows how to use the cartItemPrice filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust cart item price of the order summary items.
registerCheckoutFilters( 'example-extension', {
  cartItemPrice: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Summary context.
    // We must return the original value we received here.
    if ( args?.context !== 'summary' ) {
      return value;
    }
    return '<price/> for all items';
  }
} );

Order Summary Items » cartItemClass

The cartItemClass filter allows adding a custom class to the order summary items.

The following code snippet shows how to use the cartItemClass filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust cart item class of the order summary items.
registerCheckoutFilters( 'example-extension', {
  cartItemClass: ( value, extensions, args ) => {
    // Return early since this filter is not being applied in the Summary context.
    // We must return the original value we received here.
    if ( args?.context !== 'summary' ) {
      return value;
    }
    return 'my-custom-class';
  }
} );

Proceed to Checkout Button Label

The proceedToCheckoutButtonLabel filter allows changing the text of the proceed to checkout button label.

The following code snippet shows how to use the proceedToCheckoutButtonLabel filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust the proceed to checkout button label.
registerCheckoutFilters( 'example-extension', {
  proceedToCheckoutButtonLabel: ( value, extensions, args ) => {
    if ( ! args?.cart.items ) {
      return value;
    }

    const isSunglassesInCart = args?.cart.items.some(
      ( item ) => item.name === 'Sunglasses'
    );

    // Return the default value if sunglasses is not in the cart.
    if ( ! isSunglassesInCart ) {
      return value;
    }

    return 'Proceed to 😎 checkout';
  }
} );

Proceed to Checkout Button Link

The proceedToCheckoutButtonLink filter allows changing the text of the proceed to checkout button link.

The following code snippet shows how to use the proceedToCheckoutButtonLink filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust the proceed to checkout button link.
registerCheckoutFilters( 'example-extension', {
  proceedToCheckoutButtonLink: ( value, extensions, args ) => {
    if ( ! args?.cart.items ) {
      return value;
    }

    const isSunglassesInCart = args?.cart.items.some(
      ( item ) => item.name === 'Sunglasses'
    );

    // Return the default value if sunglasses is not in the cart.
    if ( ! isSunglassesInCart ) {
      return value;
    }

    return '/sunglasses-checkout';
  }
} );

Place Order Button Label

The placeOrderButtonLabel filter allows changing the text of the place order button link.

The following code snippet shows how to use the placeOrderButtonLabel filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust the place order button label.
registerCheckoutFilters( 'example-extension', {
  placeOrderButtonLabel: ( value, extensions, args ) => {
    return '💰 Pay now 💰';
  }
} );

Snackbar Notices » showApplyCouponNotice

The showApplyCouponNotice filter allows hiding the add coupon notice.

The following code code snippet shows how to use the showApplyCouponNotice filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Prevent a couponCode called '10off' from creating a notice when it gets applied.
registerCheckoutFilters( 'example-extension', {
  showApplyCouponNotice: ( value, extensions, args ) => {
    return args?.couponCode === '10off' ? false : value;
  }
} );

Snackbar Notices » showRemoveCouponNotice

The showRemoveCouponNotice filter allows hiding the remove coupon notice.

The following code snippet shows how to use the showRemoveCouponNotice filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Prevent a couponCode called '10off' from creating a notice when it gets removed.
registerCheckoutFilters( 'example-extension', {
  showRemoveCouponNotice: ( value, extensions, args ) => {
    return args?.couponCode === '10off' ? false : value;
  }
} );

Totals Footer Item

Changing the wording of the Totals label in the Cart and Checkout blocks using the totalLabel filter.

BeforeAfter

The following code snippet shows how to use the totalLabel filter:

const { registerCheckoutFilters } = window.wc.blocksCheckout;

// Adjust the total label.
registerCheckoutFilters( 'example-extension', {
  totalLabel: ( value, extensions, args ) => {
    return 'Deposit due today';
  }
} );

Learn more

For a full overview, head to our GitHub documentation:

Next Stop: Payment Gateways in the Checkout

In our next article, we’ll introduce the tools available to help you manage and integrate payment gateways as part of customizing your Cart and Checkout block experience.

In the meantime, if you have any questions during the integration process, our recommendation is to reach out on our GitHub Discussions section Q&A – Extension Integrations and Customizations or in the Community Slack #woocommerce-blocks-and-block-themes channel.


10 responses to “Getting to Know Woo: Modifying existing Cart and Checkout Block Fields”

  1. As far as I understand the inner blocks, as presented in chapter 2 of the tutorial series, need the Node.js environment to build the scripts, while the JS filter snippets from this chapter can be simply output in the page’s HTML without running them through the Node.js environment. Is that correct?

    And note, the first screenshot (where on the page should the code snippet load) is from the “Simple Custom CSS and JS” plugin, while you’ve referenced another plugin in a previous sentence.

    1. Hi Diana, thanks for your comment.

      As far as I understand the inner blocks, as presented in chapter 2 of the tutorial series, need the Node.js environment to build the scripts, while the JS filter snippets from this chapter can be simply output in the page’s HTML without running them through the Node.js environment. Is that correct?

      Inner blocks can technically be created without using a build tool (e.g. webpack) to process them, but we’d still recommend using one to make your development process easier.

      We illustrated using the filters by accessing the method like so:

      const { registerCheckoutFilters } = window.wc.blocksCheckout; which will work fine, as the configuration you’d add to your build process would just map the alias in your code to this global variable anyway.

      And note, the first screenshot (where on the page should the code snippet load) is from the “Simple Custom CSS and JS” plugin, while you’ve referenced another plugin in a previous sentence.

      Thanks, I’ll ping the authors to take a look!

    2. And note, the first screenshot (where on the page should the code snippet load) is from the “Simple Custom CSS and JS” plugin, while you’ve referenced another plugin in a previous sentence.

      Thanks for mentioning this, Diana. I just corrected this.

  2. don’t forget to update the internal links to this article, the url changed. You have 404 from the previous article now
    otherwise, thanks !

    1. Thanks for reaching out, mdxfr. Can you tell me which link you are referring to? I can’t seem to find it currently.

  3. As far as I understand the inner blocks, as presented in chapter 2 of the tutorial series, need the Node.js environment to build the scripts, while the JS filter snippets from this chapter can be simply output in the page’s HTML without running them through the Node.js environment. Did I understand that correctly?

    And note, the first screenshot (where on the page should the code snippet load) is from the “Simple Custom CSS and JS” plugin, while you’ve referenced another plugin in a previous sentence.

  4. helphighaddons Avatar
    helphighaddons

    Hi Thomas Roberts,

    Which file I have to place the code of registerCheckoutFilters or where I have to include the file having registerCheckoutFilters filter.

    Thank you.

    1. Hi there, the actual location you place it is up to you, but you’ll need to ensure that the JavaScript file containing this is loaded on your page. Most people use a build tool like webpack to bundle their code into a file (or set of files) that are enqueued.

      You may take a look at the `@woocommerce/extend-cart-checkout-block template to see an example of this.

  5. Muhammad Naveed Afridi Avatar
    Muhammad Naveed Afridi

    Hi,

    How we can use wp_options table data inside the blocks as we use wp_localize_script in PHP for Javascript.

    Thank you.

    1. Hi there, I’d recommend taking a look at the IntegrationInterface and specifically the enqeue_script_data method of this. In this method you could select the values you want from the wp_options table and then have them sent to the front-end via this function.

      To access them on the front end, check the Getting data added in get_script_data section. I hope this is useful!

      Feel free to open a discussion on our GitHub repository if you need more help!

Leave a Reply

Your email address will not be published. Required fields are marked *