How to add a new step in checkout page Magento 2

We all know that Magento 2 checkout’s flow contains 2 steps. The Shipping and the Payment & Review steps. For personal uses, you may want to add some additional logic like separating Payment and Review to individual step or creating a brand new step for your own customization.

This topic will guide you to create a new step checkout in magenot 2. This step particularly does one thing, let user know whether they are logged in or not. Not much a real situation but we will get into advanced topics later.

Adding a new step to checkout page.

  • Step 1: Create the .js file implementing the view model.
  • Step 2: Create an .html template for the component.
  • Step 3: Add the new step to the Checkout page layout.

You should know how to create a basic Magento 2 module. All of customized files will be inside this module.

Let’s begin.

Step 1: Create the .js file implementing the view model.

Create the checkout-login-step.js file under Mageplaza/HelloWorld/view/frontend/web/js/view directory.
Basically, we need step_code, step_title, order and the condition that allows to display this step.

Here is the code (Read code comment to get more info)

define(
    [
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Customer/js/model/customer'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator,
        customer
    ) {
        'use strict';
        /**
        * check-login - is the name of the component's .html template
        */
        return Component.extend({
            defaults: {
                template: 'Mageplaza_HelloWorld/check-login'
            },

            //add here your logic to display step,
            isVisible: ko.observable(true),
            isLogedIn: customer.isLoggedIn(),
            //step code will be used as step content id in the component template
            stepCode: 'isLogedCheck',
            //step title value
            stepTitle: 'Logging Status',

            /**
            *
            * @returns {*}
            */
            initialize: function () {
                this._super();
                // register your step
                stepNavigator.registerStep(
                    this.stepCode,
                    //step alias
                    null,
                    this.stepTitle,
                    //observable property with logic when display step or hide step
                    this.isVisible,

                    _.bind(this.navigate, this),

                    /**
                    * sort order value
                    * 'sort order value' < 10: step displays before shipping step;
                    * 10 < 'sort order value' < 20 : step displays between shipping and payment step
                    * 'sort order value' > 20 : step displays after payment step
                    */
                    15
                );

                return this;
            },

            /**
            * The navigate() method is responsible for navigation between checkout step
            * during checkout. You can add custom logic, for example some conditions
            * for switching to your custom step
            */
            navigate: function () {

            },

            /**
            * @returns void
            */
            navigateToNextStep: function () {
                stepNavigator.next();
            }
        });
    }
);

Step 2: Create an .html template for the component.

In the above step, we use Mageplaza_HelloWorld/check-login as our template, let’s create it.
Create a new html file named check-login.html under Mageplaza/HelloWorld/view/frontend/web/template directory.

Here is the code

<!--Use 'stepCode' as id attribute-->
<li data-bind="fadeVisible: isVisible, attr: { id: stepCode }">
<div class="step-title" data-bind="i18n: stepTitle" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
         <p>The customer is <span data-bind="if: !isLogedIn">not</span> Logged-in</p>
        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

Step 3: Add the new step to the Checkout page layout.

We need to extend the checkout page’s layout to be able to display the new step
Add this file in our module: Mageplaza/HelloWorld/view/frontend/layout/checkout_index_index.xml
The content as follow:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="components" xsi:type="array">
                            <item name="checkout" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="steps" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <!-- The new step you add -->
                                            <item name="check-login-step" xsi:type="array">
                                                <item name="component" xsi:type="string">Mageplaza_HelloWorld/js/view/check-login-step</item>
                                                    <!--To display step content before shipping step "sortOrder" value should be < 1-->
                                                    <!--To display step content between shipping step and payment step  1 < "sortOrder" < 2 -->
                                                    <!--To display step content after payment step "sortOrder" > 2 -->
                                                <item name="sortOrder" xsi:type="string">2</item>
                                                <item name="children" xsi:type="array">
                                                    <!--add here child component declaration for your step-->
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
        </referenceBlock>
    </body>
</page>

That’s the steps to add a new step to checkout page.
Clean cache, refresh your browser, the result will appear like this
check login step

Comments for Add a custom checkout step

Please leave comments if you have any questions, feedbacks.