How To Add CMS Block In Checkout Page Magento 2

CMS blocks was one of the reasons which made Magento was and is that popular. Site administrator can easily manipulate the content of the store using CMS blocks.

However, adding a CMS block to the Checkout page in Magento 2 is a bit more complicated than usual. This is because the whole checkout process is dynamically loaded and we cannot put anything static inside it. Therefore, in today post, I will guide you on how to add CMS block to Magento 2 Checkout.

How to add CMS Block in checkout page

Step 1: Create a module

In case you have not known the way to create a Magento 2 module, you can follow the steps the post How to Create Module in Magento 2

You can set the name of the module as you want. In this article, I will use Mageplaza for vendor and ModuleName for module name.

After the module has been created with all the necessary files, you will need to add or edit some details of it.

But before doing that, please make sure that you have done setup:upgrade after creating the module.

Step 2: Add CMS block in Checkout sidebar

In this step, you will edit the Mageplaza/ModuleName/etc/frontend/di.xml file:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Checkout\Model\CompositeConfigProvider">
       <arguments>
           <argument name="configProviders" xsi:type="array">
               <item name="cms_block_config_provider" xsi:type="object">Mageplaza\ModuleName\Model\ConfigProvider</item>
           </argument>
       </arguments>
   </type>
   <type name="Mageplaza\ModuleName\Model\ConfigProvider">
       <arguments>
           <argument name="blockId" xsi:type="string">checkout_cms_block</argument>
       </arguments>
   </type>
</config>

Using this code, a new entry to ConfigProvider is added as well as CMS block which will be used to parse data from is declared.

In the example above, the name of the block is checkout_cms_block. This would work with the block’s ID or identifier.

Remember that the path Mageplaza\ModuleName\Model\ConfigProvider need to be matched with the name of your block.

Then, by creating or editing Mageplaza/ModuleName/Model/ConfigProvider.php, you will create a new entry for Config Provider:

<?php namespace Mageplaza\ModuleName\Model;
 
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Framework\View\LayoutInterface;
 
class ConfigProvider implements ConfigProviderInterface
{
   /** @var LayoutInterface  */
   protected $_layout;
   protected $cmsBlock;
 
   public function __construct(LayoutInterface $layout, $blockId)
   {
       $this->_layout = $layout;
       $this->cmsBlock = $this->constructBlock($blockId);
   }
 
   public function constructBlock($blockId){
       $block = $this->_layout->createBlock('Magento\Cms\Block\Block')
           ->setBlockId($blockId)->toHtml();
       return $block;
   }
 
   public function getConfig()
   {
       return [
           'cms_block' => $this->cmsBlock
       ];
   }
}

Because the variable has beed added to global window.checkoutConfig variable, now you can use window.checkoutConfig.cms_block variable to call that content.

Next, bind that variable to some HTML element. The rest will be in charge of Knockout.JS.

Following is the file app/design/frontend/Mageplaza/ThemeName/Magento_Checkout/web/template/sidebar.html

 <div id="opc-sidebar"
    data-bind="afterRender:setModalElement, mageInit: {
   'Magento_Ui/js/modal/modal':{
       'type': 'custom',
       'modalClass': 'opc-sidebar opc-summary-wrapper',
       'wrapperClass': 'checkout-container',
       'parentModalClass': '_has-modal-custom',
       'responsive': true,
       'responsiveClass': 'custom-slide',
       'overlayClass': 'modal-custom-overlay',
       'buttons': []
   }}">
 
   <!-- ko foreach: getRegion('summary') -->
       <!-- ko template: getTemplate() --><!-- /ko -->
   <!--/ko-->
 
   <div data-bind="html: window.checkoutConfig.cms_block"></div>
 
   <div class="opc-block-shipping-information">
       <!-- ko foreach: getRegion('shipping-information') -->
       <!-- ko template: getTemplate() --><!-- /ko -->
       <!--/ko-->
   </div>
</div>

After following all the steps correctly, you will see your CMS block being displayed in the sidebar.

Step 3: Add CMS block to address form

Instead of using a similar approach, in this step, we will change the content of app/code/Mageplaza/ModuleName/Model/ConfigProvider.php. The content will be changed into this:

<?php
 
namespace Mageplaza\ModuleName\Model;
 
 
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Cms\Block\Widget\Block;
 
class ConfigProvider implements ConfigProviderInterface
{
   protected $cmsBlockWidget;
 
   public function __construct(Block $block, $blockId)
   {
       $this->cmsBlockWidget = $block;
       $block->setData('block_id', $blockId);
       $block->setTemplate('Magento_Cms::widget/static_block/default.phtml');
   }
 
   public function getConfig()
   {
       return [
           'cms_block' => $this->cmsBlockWidget->toHtml()
       ];
   }
}

Next, you create app/code/Mageplaza/ModuleName/view/frontend/layout/checkout_index_index.xml with the following content:

<?xml version="1.0"?>
 
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" 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">
                                       <item name="shipping-step" xsi:type="array">
                                           <item name="children" xsi:type="array">
                                               <item name="shippingAddress" xsi:type="array">
                                                   <item name="children" xsi:type="array">
                                                       <item name="shipping-address-fieldset" xsi:type="array">
                                                           <item name="children" xsi:type="array">
                                                               <item name="cms-block" xsi:type="array">
                                                                   <item name="component" xsi:type="string">uiComponent</item>
                                                                   <item name="config" xsi:type="array">
                                                                       <item name="template" xsi:type="string">Mageplaza_ModuleName/cms-block</item>
                                                                   </item>
                                                                   <item name="sortOrder" xsi:type="string">1</item>
                                                               </item>
                                                           </item>
                                                       </item>
                                                   </item>
                                               </item>
                                           </item>
                                       </item>
                                   </item>
                               </item>
                           </item>
                       </item>
                   </item>
               </argument>
           </arguments>
       </referenceBlock>
   </body>
</page>

Now, the new UIcomponent has been added to the address form. The content of your CMS block will be held in that component. The components load order would be managed inside XML files. You might see that the sortOrder has been set as 1, which means that your component will be loaded first inside address form.

Pay attention to the line Mageplaza_ModuleName/cms-block and then change it.

Now, the only thing you need is a knockout template to output the CMS block data.

Use this content to create app/code/Mageplaza/ModuleName/view/frontend/web/template/cms-block.html:

<div data-bind="html: window.checkoutConfig.cms_block"></div>

Following all the steps above, you will see your CMS block being displayed in address form and rendered first. This guide will work with clean Magento 2.2 installation. If for testing purposes, the Luma theme can be used.

Conclusion

Above is the instruction on how to add CMS Block in checkout page Magento 2. Hope it will be helpful for you. In case something went wrong, please ensure:

  • Your module is created properly and all config files with proper values have consisted inside.
  • The php bin/magento setup:upgrade need to be run after the module is created.
  • The code Mageplaza/ModuleName from this post need to be replaced with the proper vendor and name of your module.

Enjoyed the tutorial? Spread it to your friends!