Tutorial: Extending the WooCommerce Checkout Block

Simply adding a field to Checkout?

If you’re trying to add a simple field to checkout block (text, checkbox, select), you can do that right now using PHP only, via the additional fields API.

A few weeks ago, I was lucky enough to be at WCEU 2023 – Athens and had the opportunity to attend some of the workshops. In the workshop by Thomas Roberts (@opr18) and Niels Lange (@nielslange), we walked through the process of extending the WooCommerce Checkout block to include a “Not at home” shipping option. 

The workshop delved into the extensibility interfaces offered by WooCommerce Blocks, demonstrating how they can be utilized to modify and personalize the WooCommerce Checkout block.

The tutorial

The tutorial uses a code package which consists primarily of JavaScript and some PHP code that can be used to enhance the shipping functionality of your WooCommerce store. You may follow the step-by-step instructions available inside the code package itself, or you may follow the guided video tutorial at the end of this post.

Spoiler: A completed version of the tutorial can be found at this GitHub repository.

Prerequisites

Before we begin, make sure you have met the following requirements:

  1. A development environment with a blank WP installation (e.g., Local by Flywheel)
  2. WooCommerce plugin installed and activated
  3. Checkout page with the WooCommerce Checkout block added
  4. Basic knowledge of JavaScript (React)
  5. IDE/Code editor (e.g., Visual Studio Code)
  6. Node or NVM (Node Version Manager) installed
  7. Redux Dev Tools installed (Chromium / Firefox)

Getting started

  1. From your terminal, go to the folder wp-content/plugins
  2. Run npx @wordpress/create-block -t wceu23-shipping-workshop shipping-workshop to create a new block project called shipping-workshop
  3. Set up a shipping method and payment method in your WordPress site. The workshop recommends using Cash on Delivery or Bank transfer as they are the easiest methods to set up
  4. Navigate to the shipping-workshop directory using the command cd shipping-workshop
  5. Install the Prettier package by running npm i -D prettier@npm:wp-prettier@2.6.2
  6. Start the development server by running npm run start

Understanding the Code

To understand and utilize the code, it is important to have a basic understanding of React and the Gutenberg block editor. If you are new to React or Gutenberg, we recommend referring to the official documentation:

Files needed for the implementation

The index.js file in the project folder is configured as the entry point for Webpack when building the final files. It is responsible for importing and registering the block type on WordPress. This file typically imports the block’s edit.js and save.js files and registers the block using the registerBlockType function provided by the @wordpress/blocks package.

The edit.js file is responsible for rendering the block in the Gutenberg editor interface. The edit function describes the structure of your block in the context of the editor. It is used to define the block’s edit mode.

The block.json file provides metadata about the block. It defines the block’s name, title, icon, category, attributes, and other settings. 

  • The lock attribute is an object that controls whether the block can be removed or moved. By default, the lock attribute is set to allow the block to be removed and moved. However, by modifying the lock attribute, you can “force” the block to be non-removable. For example, you can set both remove and move properties to false in order to prevent the block from being removed or moved.
  • The parent attribute specifies the parent block that this block should be nested within it. It determines where the block will render. In our example, the block is a child of the woocommerce/checkout-shipping-methods-block. This means that the shipping-workshop-block will be rendered within the woocommerce/checkout-shipping-methods-block.

The block.js file in our example is the main entry point for the block and handles the block’s state and user interactions in the editor and frontend.

The frontend.js file registers the block’s component with the WordPress editor using the registerCheckoutBlock function from the @woocommerce/blocks-checkout package. It imports the block’s component, metadata, and other necessary dependencies, and ultimately handles the component in the frontend. This is an API exposed by WooCommerce as an official way for registering frontend rendered React components for the Checkout block.

The options.js file is used to list and define the extended shipping options.

The shipping-workshop-blocks-integration.php file handles the integration and functionality of the checkout-shipping-methods-block in WooCommerce. It registers scripts and styles and handles the saving and displaying of shipping instructions.

The shipping-workshop-extend-store-endpoint.php extends the Store API and adds hooks to save and display shipping instructions. 

Updating the code

To customize the WooCommerce Shipping Workshop Block, you can follow the instructions provided in the code comments that start with the 📝 emoji. These comments highlight areas where you can make modifications or updates.

For example:

/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
export const options = [
	{
		label: __( 'Try again another day', 'shipping-workshop' ),
		value: 'try-again',
	},
	/**
	 * [frontend-step-01]
	 * 📝 Add more options using the same format as above. Ensure one option has the key "other".
	 */
];

In this section, you will want to follow the instructions to add more options to the list. The result would look something like this:

export const options = [
	{
		label: __( 'Try again another day', 'shipping-workshop' ),
		value: 'try-again',
	},
	{
	    label: __( 'Leave with neighbour', 'shipping-workshop' ),
	    value: 'leave-with-neighbour',
    },
    {
	    label: __( 'Leave in shed', 'shipping-workshop' ),
	    value: 'leave-in-shed',
    },
    {
	    label: __( 'Other', 'shipping-workshop' ),
	    value: 'other',
    },
];

🛟 Feeling stuck? We have some lifesavers 

Feeling stuck and not sure how to solve the 📝Step you are on? You can always refer to the completed project here to unblock yourself, or you can refer to the /spoilers folder inside your repo or in the completed package here to find solutions to specific prompts in the 📝Step code comments.

🎥 Video tutorial

Thomas Roberts provides a step-by-step walk-through of the tutorial

Keep yourself in the loop!

Sign up for the WooCommerce developer newsletter:
This field is hidden when viewing the form
This field is hidden when viewing the form
This field is hidden when viewing the form


8 responses to “Tutorial: Extending the WooCommerce Checkout Block”

  1. Thank you very much for this tutorial!
    We liked it a lot, especially because it is a short one with a lot of information. We would like to see more tutorials like this because we still have problems with development in REACT / blocks.

    The spoiler for “frontend-step-02-extra-credit-2” contains only “TBD” (so does “frontend-step-04-extra-credit.md” and “frontend-step-07-extra-credit.md”). Could you please add this?

    1. Hi lars thanks for taking the time to work through our tutorial, and thanks for the feedback!

      You’re right we were missing content from those files, however we’ve updated them now so if you pull the latest changes from the https://github.com/woocommerce/wceu23-shipping-workshop-final repository they’ll be included. They’ll also be included in any new plugins created with @wordpress/create-block and using our template.

  2. Hi, thank you very much for this tutorial. There is an aspect missing and I cannot figure out how to implement it. I need to ass some attributes to the custom block, editable using the block properties sidebar. Adding the attributes it’s easy but on block.js, where the block is implemented, I cannot find out how to access the block attributes.

    An attribute example could be a true/false value to exclude one of the delivery options.

    Thanks!

    1. Hello, did you found a solution for your problem?

  3. Vikas Raghuwanshi Avatar
    Vikas Raghuwanshi

    Hi Thomas,
    Thank your for the exellent tutorial.
    I have created a custom woocomerce extension, that provides discounts by creating deals at the backend. I am using woocommerce actions and filters to add discount labels, quantity validations etc. I need to customize product archive, cart and checkout page.

    But now as soon as, I switched to woocommerce blocks, all hooks stopped working.
    Is there any way, I can make my plugin block compatible?
    As I followed the tutorial, I reckon, I need to create new block extension plugin.
    It would be great, if you can provide your insights on this.

  4. Hello,

    How can we use the block attributes in block.js? They are not passed.

    For example, in your tutorial, you can customize the “If I am not at home please…” text in the editor via a RichText in edit.js: https://github.com/woocommerce/wceu23-shipping-workshop-final/blob/main/src/js/shipping-workshop-block/edit.js#L32-L42

    However, this text do not change accordingly on the frontend, because it is hardcoded in block.js: https://github.com/woocommerce/wceu23-shipping-workshop-final/blob/main/src/js/shipping-workshop-block/block.js#L188-L191

  5. So what i will do with all 9 plugins i develope and sell
    no hooking work any more what to tell to the customers?

    1. Nadir Seghir Avatar
      Nadir Seghir

      Hey Dano! How can we help you integrate your plugins? is anything missing right now that we can add/document better?

      We do provide regular, daily support in our WooCommerce Slack channels where you have direct access to WooCommerce engineers.

Leave a Reply

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