Skip to main content

Adding a new field to the mini cart in Magento 2

· 4 min read

In this tutorial, we will add a new field "Discount" to the mini cart. That is, if the customer got a discount in his cart, he would now be able to see it in the mini cart.

For example, we created a cart rule that applies a 10% discount on bags.

Here is how the current mini cart looks like with the cart rule applied -

The mini cart in Magento 2 before the changes - the applied discount is not showing up in the mini cart

You can see that the discount doesn’t show up in the mini cart, even though it was applied in the cart -

The cart has the discount amount

And here is how it will look after our changes -

The mini cart after applying our changes - the discount amount line is showing up in the mini cart

So let’s go ahead and create our module.

Step 1: Create the basic file structure for your module

Here is how our module’s file structure will look like -

Our module's file structure

Create the folder app/code/Myvendor/Mymodule and add the following files:

app/code/Myvendor/Mymodule/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Myvendor_Mymodule" setup_version="1.0.0" />
</config>
app/code/Myvendor/Mymodule/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Myvendor_Mymodule',
__DIR__
);

Now when you have the basic module structure, lets proceed to the actual files that will add the "Discount" field to the mini cart.

Step 2: Add the new minicart field to the layout xml file and create the template files

app/code/Myvendor/Mymodule/view/frontend/layout/checkout_cart_sidebar_item_renderers.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="minicart">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="minicart_content" xsi:type="array">
<item name="children" xsi:type="array">
<item name="discount.container" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="config" xsi:type="array">
<item name="displayArea" xsi:type="string">subtotalContainer</item>
</item>
<item name="children" xsi:type="array">
<item name="subtotal" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/checkout/minicart/subtotal/totals</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Myvendor_Mymodule/minicart/discount</item>
</item>
<item name="children" xsi:type="array">
<item name="subtotal.totals" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/checkout/minicart/subtotal/totals</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Myvendor_Mymodule/minicart/discount/inner</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>

This file tells Magento to add the “Discount” as a child in the minicart and sets our template files to it. Now let's add the template files.

app/code/Myvendor/Mymodule/view/frontend/web/template/minicart/discount.html
<!-- ko if: (cart().discount_amount_no_html < 0) -->
<div class="subtotal">
<span class="label">
<!-- ko i18n: 'Discount' --><!-- /ko -->
</span>

<!-- ko foreach: elems -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
</div>
<!-- /ko -->
app/code/Myvendor/Mymodule/view/frontend/web/template/minicart/discount/inner.html
<!-- ko if: (cart().discount_amount_no_html < 0) -->
<div class="amount price-container">
<span class="price-wrapper" data-bind="html: cart().discount_amount"></span>
</div>

Step 3: Provide the value of the new field to be fetched on the frontend

Now the only thing left to do is to provide the value of the “Discount” field to the class \Magento\Checkout\CustomerData\Cart that will be fetched by the minicart on the frontend. To do that, we will use a plugin.

app/code/Myvendor/Mymodule/etc/di.xml
<?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\CustomerData\Cart">
<plugin name="cartPrivateDataDiscount" type="Myvendor\Mymodule\Plugin\Checkout\CustomerData\Cart"/>
</type>
</config>
app/code/Myvendor/Mymodule/Plugin/Checkout/CustomerData/Cart.php
<?php
namespace Myvendor\Mymodule\Plugin\Checkout\CustomerData;

class Cart
{
protected $checkoutSession;
protected $checkoutHelper;
protected $quote;

public function __construct(
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Checkout\Helper\Data $checkoutHelper
) {
$this->checkoutSession = $checkoutSession;
$this->checkoutHelper = $checkoutHelper;
}

/**
* Get active quote
*
* @return \Magento\Quote\Model\Quote
*/
protected function getQuote()
{
if (null === $this->quote) {
$this->quote = $this->checkoutSession->getQuote();
}
return $this->quote;
}

protected function getDiscountAmount()
{
$discountAmount = 0;
foreach($this->getQuote()->getAllVisibleItems() as $item){
$discountAmount += ($item->getDiscountAmount() ? $item->getDiscountAmount() : 0);
}
return $discountAmount;
}

public function afterGetSectionData(\Magento\Checkout\CustomerData\Cart $subject, $result)
{
$result['discount_amount_no_html'] = -$this->getDiscountAmount();
$result['discount_amount'] = $this->checkoutHelper->formatPrice(-$this->getDiscountAmount());

return $result;
}
}

Testing the module

Now it’s time to test our module.

First, create a cart rule that gives us a 10% discount on the product from the “Bags” category. Afterward, install the module by running the following commands in your SSH:

php bin/magento module:enable Myvendor_Mymodule --clear-static-content
php bin/magento setup:upgrade

If you running Magento on the default or a developer mode, run the following commands:

php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush

Otherwise, if you running Magento on the production mode, run the following commands:

php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento cache:flush

Now try adding a bag to your cart. You should be able to see the discount line in the minicart -

The mini cart after applying our changes - the discount amount line is showing up in the mini cart

Summing up

In this tutorial, we demonstrated how to add a new field to the mini cart.

Although Magento 2 is quite sophisticated to develop on, once you know how to do that, it is quite easy. Also, the implementations for features on Magento 2 are usually quite elegant because of Magento 2 sophisticated architecture.