Magento 2: Get Custom Attribute in Customerdata Cart

Magento 2: Get Custom Attribute in Customerdata Cart

[Updated: March 02, 2026]

Custom product attributes do not appear in the Magento 2 minicart or checkout by default. This guide shows you how to inject them through plugins, display them in Knockout.js templates, and debug common issues.

Key Takeaways

  • Magento 2 does not expose custom product attributes in the cart by default. You need a plugin on DefaultItem::getItemData.
  • Since Magento 2.4.4+, many standard attributes (weight, sku) load with quote items by default. For custom attributes, use catalog_attributes.xml.
  • afterGetItemData is the recommended plugin type for adding data. aroundGetItemData is for modifying existing data.
  • The same pattern works for the minicart (via DefaultItem) and the checkout summary (via DefaultConfigProvider).
  • Configurable products require extra handling to access child product attributes.

What is customerData in Magento 2?

customerData = Magento's client-side data framework for private, user-specific content. It stores cart items, wishlist data, and customer info in localStorage and refreshes via AJAX after state-changing actions.

Perfect for: Developers adding custom product data to the minicart, checkout summary, or cart sidebar.

Not ideal for: Static product data that belongs in catalog pages or public cache layers.

Magento 2 separates public content (cacheable by Varnish/CDN) from private content (unique per user). The customerData JavaScript object manages all private content on the frontend.

The cart section is one of the most used customerData sections. It powers the minicart dropdown, the cart sidebar, and parts of the checkout page. Every cart item in this section contains default properties like product_name, qty, and product_price.

Custom attributes (brand name, delivery estimate, "Pre-Order" flags) are not included in this default data set. To expose them, you inject additional key-value pairs through a PHP plugin on Magento\Checkout\CustomerData\DefaultItem.

Once injected, these attributes become accessible through JavaScript via customerData.get('cart'). This opens the door to richer Magento storefronts with dynamic minicart labels, conditional checkout logic, and frontend-driven personalization.

How customerData Cart Sections Work

Understanding the data flow helps you debug issues later. Here is what happens when a customer adds a product to the cart:

1. Browser sends an add-to-cart request to Magento.

2. Magento invalidates the cart section. The etc/frontend/sections.xml file maps controller actions to section names. The default checkout/cart/add action triggers a cart section refresh.

3. Browser requests fresh section data from /customer/section/load/?sections=cart.

4. Magento builds the response. For each cart item, DefaultItem::getItemData() assembles the data array. This is where your plugin intercepts the process and adds custom attributes.

5. Browser stores the response in localStorage under mage-cache-storage. Knockout.js components like the minicart read from this store and re-render.

This cycle repeats on every cart modification. Your custom attribute rides along with each refresh.

Step-by-Step: Add a Custom Attribute to the Minicart

This tutorial adds a weight attribute to the minicart. Replace weight with any product attribute you need.

Step 1: Register the Attribute in catalog_attributes.xml

Create Vendor/Module/etc/catalog_attributes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="weight"/>
    </group>
</config>

This tells Magento to load the weight attribute when building quote items. The quote_item group is the performance-safe approach. It avoids loading the full product object for each cart item.

Note on Magento 2.4.4+: Since Magento 2.4.4, many standard attributes like weight and sku already load with quote items by default. You may not need this file for common attributes. If your attribute returns null in the plugin, create this file first. For custom EAV attributes (e.g. vendor_delivery_date), this step is always required.

Step 2: Create the Plugin Declaration in di.xml

Create Vendor/Module/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\DefaultItem">
        <plugin name="vendor_module_custom_cart_data"
                type="Vendor\Module\Plugin\DefaultItemPlugin"/>
    </type>
</config>

This declares a plugin on DefaultItem. Magento's plugin system intercepts the getItemData method call and lets you append your data.

Step 3: Build the Plugin Class

Create Vendor/Module/Plugin/DefaultItemPlugin.php:

<?php
declare(strict_types=1);

namespace Vendor\Module\Plugin;

use Magento\Checkout\CustomerData\DefaultItem;

class DefaultItemPlugin
{
    public function afterGetItemData(
        DefaultItem $subject,
        array $result
    ): array {
        $item = $subject->getItem();

        // Preferred: getData() reads from the quote item directly
        // No extra product load required
        $result['weight'] = $item->getData('weight');

        return $result;
    }
}

The afterGetItemData method receives the original data array as $result. You add your custom key and return the modified array.

Why getData() over getProduct()->getWeight()? Calling $item->getData('weight') reads the value from the quote item object. No extra product load. Calling $item->getProduct()->getWeight() triggers a full product model load for each cart item. For a cart with 20 items, that means 20 extra database queries. Always prefer getData() when the attribute is registered in catalog_attributes.xml or loaded by default (2.4.4+).

Step 4: Override the Minicart Template

Copy the default template to your theme:

app/design/frontend/Vendor/Theme/Magento_Checkout/web/template/minicart/item/default.html

Add your custom attribute where you want it displayed:

<div class="product-weight" data-bind="visible: weight">
    <span data-bind="text: 'Weight: ' + weight + ' kg'"></span>
</div>

The data-bind="visible: weight" hides the block when the attribute is falsy. This is cleaner than the <!-- ko if --> comment syntax and easier to read. Both approaches work. Knockout.js templates in Magento 2 support both patterns.

Hyvä and PWA note: This template override applies to the default Luma/Blank theme using Knockout.js. If your store runs on a Hyvä theme, you need an Alpine.js override or a PHP ViewModel instead. For PWA Studio or other headless frontends, extend the GraphQL cart item resolver rather than using customerData.

Step 5: Clear Cache and Verify

Run these commands:

bin/magento cache:clean
bin/magento cache:flush

Then open your browser, add a product with a weight value to the cart, and check the minicart. You should see the weight label.

Quick verification via browser console:

require(['Magento_Customer/js/customer-data'], function(customerData) {
    var cart = customerData.get('cart')();
    console.log(cart.items[0].weight);
});

If the value is undefined, check Step 1 (is catalog_attributes.xml correct?) and clear the cache again.

afterGetItemData vs aroundGetItemData

Both plugin types work for injecting custom data. Here is when to use which:

Feature afterGetItemData aroundGetItemData
Use case Add new data to the result Modify or remove existing data
Complexity Low (receives result, returns it) Higher (must call $proceed())
Performance Better (no wrapping overhead) Slight overhead
Can block original method No Yes
Magento recommendation Preferred for adding data Use only when after is insufficient

Use afterGetItemData when you add custom keys to the cart data array. This is the case for 90% of implementations.

Use aroundGetItemData when you need to modify existing keys, conditionally skip the original method, or transform the entire result structure.

// aroundGetItemData example (only when needed)
public function aroundGetItemData(
    DefaultItem $subject,
    callable $proceed
): array {
    $result = $proceed();

    // Modify an existing value
    $result['product_name'] = $result['product_name'] . ' [Custom]';
    // Add new value
    $result['weight'] = $subject->getItem()->getData('weight');

    return $result;
}

Bonus: Add Custom Attributes to the Checkout Summary

The minicart and checkout summary use different data sources. The minicart reads from customerData.get('cart'). The checkout summary reads from window.checkoutConfig.quoteItemData.

To show your custom attribute in the checkout summary, you need a second plugin.

Plugin on DefaultConfigProvider

Create Vendor/Module/Plugin/ConfigProviderPlugin.php:

<?php
declare(strict_types=1);

namespace Vendor\Module\Plugin;

use Magento\Checkout\Model\DefaultConfigProvider;
use Magento\Checkout\Model\Session as CheckoutSession;

class ConfigProviderPlugin
{
    private CheckoutSession $checkoutSession;

    public function __construct(CheckoutSession $checkoutSession)
    {
        $this->checkoutSession = $checkoutSession;
    }

    public function afterGetConfig(
        DefaultConfigProvider $subject,
        array $output
    ): array {
        $quote = $this->checkoutSession->getQuote();

        foreach ($output['quoteItemData'] as &$itemData) {
            $quoteItem = $quote->getItemById($itemData['item_id']);
            if ($quoteItem) {
                $itemData['weight'] = $quoteItem->getData('weight')
                    ?? $quoteItem->getProduct()->getData('weight');
            }
        }

        return $output;
    }
}

The quote is already available through the checkout session. No need to re-load it through CartRepositoryInterface. The null-coalescing operator (??) falls back to the product-level value if the quote item does not carry the attribute.

Add to di.xml:

<type name="Magento\Checkout\Model\DefaultConfigProvider">
    <plugin name="vendor_module_checkout_config"
            type="Vendor\Module\Plugin\ConfigProviderPlugin"/>
</type>

Then override the checkout summary template to display the value.

Configurable Products: Getting the Child Attribute

For configurable products, $item->getProduct() returns the parent product. The parent may not have the same attribute values as the selected child (simple) product.

Try the quote item data first. Fall back to child product lookup only when needed:

public function afterGetItemData(
    DefaultItem $subject,
    array $result
): array {
    $item = $subject->getItem();

    // Preferred: read from quote item (works if attribute is loaded)
    $weight = $item->getData('weight');

    // Fallback for configurable products: get child product value
    if ($weight === null && $item->getProduct()->getTypeId() === 'configurable') {
        $child = $item->getOptionByCode('simple_product')?->getProduct();
        $weight = $child ? $child->getData('weight') : null;
    }

    $result['weight'] = $weight;
    return $result;
}

The first call to $item->getData('weight') covers both simple products and configurable items where the attribute is already loaded at quote level. The fallback only triggers when the value is null and the product is configurable. This avoids the full child product load in most cases.

Debugging customerData Cart Issues

Custom attributes not showing up? Walk through this checklist:

1. Check the AJAX response. Open browser DevTools. Go to the Network tab. Filter for section/load. Add a product to the cart and inspect the JSON response. Look for your custom key in the items array.

2. Inspect localStorage. Run this in the browser console:

JSON.parse(localStorage.getItem('mage-cache-storage')).cart.items[0]

If your attribute is missing here, the problem is in your PHP plugin.

3. Force a section refresh.

require(['Magento_Customer/js/customer-data'], function(customerData) {
    customerData.invalidate(['cart']);
    customerData.reload(['cart'], true);
});

The second argument true forces a fresh AJAX call, bypassing any cached response.

4. Log values in your plugin.

$logger = \Magento\Framework\App\ObjectManager::getInstance()
    ->get(\Psr\Log\LoggerInterface::class);
$logger->info('Custom attribute value: ' . $item->getData('weight'));

Check var/log/system.log for the output.

5. Verify catalog_attributes.xml is loaded.

bin/magento dev:di:info "Magento\Checkout\CustomerData\DefaultItem"

This confirms your plugin is registered. If the attribute returns null, your catalog_attributes.xml may not be in the correct path or the cache needs clearing.

When You Need sections.xml

Magento uses etc/frontend/sections.xml to map controller actions to section invalidations. The default mappings cover all standard cart actions: add, update, delete, coupon apply, and estimate shipping. In 95% of projects, you never need to touch this file.

You only need a custom sections.xml entry if your custom module has its own controller action that modifies the cart (custom AJAX add, bulk update endpoint, etc.):

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="vendor/module/cart/update">
        <section name="cart"/>
    </action>
</config>

Without this mapping, your custom action updates the server-side cart but the browser keeps showing stale data. The minicart won't reflect the change until the customer navigates to another page.

Best Practices

Limit to 3-5 custom attributes per item. Every extra attribute increases the customerData JSON response size. For a cart with 15 items, 10 custom attributes each means 150 extra data points per page load. Keep it under 5 attributes. If you need more, create a separate custom customerData section with its own AJAX endpoint.

Use catalog_attributes.xml over product loads. Loading $item->getProduct() for each cart item triggers separate database queries. The catalog_attributes.xml approach pre-loads attributes with the quote, reducing query count. For stores with 10,000+ products and high traffic, this difference is measurable.

Namespace your custom keys. Instead of generic keys like label or type, use prefixed keys like vendor_delivery_date or vendor_preorder_flag. This prevents collisions with future Magento core updates or other extensions.

Test with guest and logged-in sessions. The customerData mechanism behaves different for guest vs logged-in users. Guest data lives in a cookie-scoped localStorage. Logged-in data ties to the customer session. Test both flows.

Never expose sensitive data. The customerData cart response is visible in the browser. Do not inject internal SKU mappings, cost prices, supplier names, or customer PII. Only expose data that is safe for frontend display.

Consider separate AJAX for heavy data. For complex Magento stores with many custom attributes, create a dedicated customerData section instead of bloating the cart section. Register your section in di.xml with Magento\Customer\CustomerData\SectionPoolInterface and load it on demand.

Headless / PWA consideration. If your store uses PWA Studio, Adobe Commerce PWA, or any GraphQL-based frontend, customerData is not the right approach. Extend the cart and cart_items GraphQL resolvers instead. The customerData pattern is specific to the Luma/Knockout.js frontend. Pair your setup with reliable managed Magento hosting for consistent response times across all cart operations.

FAQ

1. What is the customerData object in Magento 2?

customerData is Magento 2's JavaScript framework for managing private, user-specific data on the frontend. It stores cart items, wishlist data, and customer info in localStorage. The browser refreshes this data via AJAX calls to /customer/section/load/ after state-changing actions.

2. Why does my custom attribute return null in the plugin?

For standard attributes like weight or sku on Magento 2.4.4+, they should load by default. Clear cache first (bin/magento cache:clean). For custom EAV attributes, create a catalog_attributes.xml file and register the attribute in the quote_item group. Also verify the attribute has a value on the product itself in the admin panel.

3. What is the difference between afterGetItemData and aroundGetItemData?

afterGetItemData runs after the original method and receives the result array. Use it to add new keys. aroundGetItemData wraps the original method and requires you to call $proceed(). Use it when you need to modify or remove existing data. Magento recommends after plugins as the default choice.

4. How do I show a custom attribute in both the minicart and checkout summary?

The minicart and checkout summary use different data sources. For the minicart, create a plugin on DefaultItem::getItemData. For the checkout summary, create a plugin on DefaultConfigProvider::getConfig and add your data to the quoteItemData array. Both plugins can live in the same module.

5. How do I get the child product attribute for configurable products?

For configurable products, $item->getProduct() returns the parent. To access the selected child, use $item->getOptionByCode('simple_product')->getProduct(). This returns the simple product the customer selected, with its own attribute values.

6. How do I debug customerData in the browser?

Open the browser console and run require(['Magento_Customer/js/customer-data'], function(cd) { console.log(cd.get('cart')()); });. This prints the full cart section data. You can also check the Network tab for the section/load AJAX request and inspect the raw JSON response.

7. Do I need sections.xml for my custom attribute?

Only if your custom module has a custom controller action that modifies the cart. Standard cart actions (add, update, delete) are already mapped. If your custom action changes cart data without triggering a section refresh, the browser will show stale data.

8. What is the performance impact of adding custom attributes to the cart?

Minimal if you use getData() on the quote item. Each attribute adds a few bytes to the JSON response. Keep it under 3-5 custom attributes per item. Avoid calling $item->getProduct() in a loop. For stores with 10,000+ SKUs and high traffic, use catalog_attributes.xml to pre-load at quote level instead of per-item product loads.

9. Can I add custom attributes to the cart page (not just minicart)?

Yes. The full cart page uses Magento layout XML and PHP block templates, not customerData. You can add attributes through a custom block or by extending the cart item renderer template in Magento_Checkout/templates/cart/item/default.phtml.

10. Does this work with Hyvä or PWA Studio?

Not directly. The customerData + Knockout.js pattern is specific to the Luma/Blank frontend. Hyvä uses Alpine.js, so you need a PHP ViewModel and an Alpine.js component instead of a KO template override. PWA Studio and other headless frontends use GraphQL. Extend the cart item GraphQL resolver to expose your attribute there.

11. How do I pass custom cart data to Google Tag Manager?

After injecting your custom attribute into customerData, you can push it to the GTM data layer through a JavaScript mixin or a custom Knockout.js component. Access the attribute via customerData.get('cart')().items and push each item's custom data to window.dataLayer.

Summary

Adding custom attributes to the Magento 2 customerData cart unlocks richer frontend experiences. The core pattern is straightforward: register the attribute in catalog_attributes.xml, create a plugin on DefaultItem, and override the minicart template.

For checkout summary visibility, add a second plugin on DefaultConfigProvider. Handle configurable products by checking for child product options. Debug with browser console inspection and PHP logging.

The catalog_attributes.xml + afterGetItemData combination is the recommended approach for Luma-based stores. It delivers the best performance with the least complexity. For Hyvä or headless setups, adapt the backend plugin pattern and replace the frontend rendering layer.

Ruby Agarwal
Ruby Agarwal
Technical Writer

Ruby is an experienced technical writer sharing well-researched Magento hosting insights. She likes to combine unique technical and marketing knowledge in her content.


Get the fastest Magento Hosting! Get Started