How to create category attribute Programmatically in Magento 2?

We can create custom category attributes with text fields programmatically in Magento 2 using a simple module.

In our demo, we have created a simple text field attribute for a category to save the value and use it on the front end.

You can see a category attribute in the backend using Catalog -> Categories Page.

Click on Any category and you can see our custom attribute in General Section after the category name.

If you are interested to create a drop-down select category attribute, Learn MoreTo create a custom category attribute we need to create Patch Data Class to define our custom category attribute name.

Let’s start with a simple custom module to create custom category attributes,
You need to create the first registration.php and module.xml files for defining our module to Magento.

Here I have used Rbj as Packagename where CategoryAttrbute is the module name.

Path: app/code/Rbj/CategoryAttribute/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Rbj_CategoryAttribute',
    __DIR__
);

Create a module.xml file, Path: app/code/Rbj/CategoryAttribute/etc/module.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Rbj_CategoryAttribute">
       <sequence>
	   <module name="Magento_Catalog"/>
       </sequence>
    </module>
</config>

module.xml depends on the Magento_Catalog module.

Create a CategoryTextAttribute.php file to define our custom category attribute, app/code/Rbj/CategoryAttribute/Setup/Patch/Data/CategoryTextAttribute.php

<?php
namespace Rbj\CategoryAttribute\Setup\Patch\Data;

use Magento\Catalog\Model\Category;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class CategoryTextAttribute implements DataPatchInterface
{
    public function __construct(
        private ModuleDataSetupInterface $moduleDataSetup,
        private EavSetupFactory $eavSetupFactory
    ) {
    }

    /**
     * {@inheritdoc}
     */
    public function apply() {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute(
            Category::ENTITY,
            'custom_category_field',
            [
                'type' => 'varchar',
                'label' => 'Category Custom field',
                'input' => 'text',
                'sort_order' => 100,
                'source' => '',
                'global' => 1,
                'visible' => true,
                'required' => false,
                'user_defined' => false,
                'default' => null,
                'group' => 'General Information'
            ]
        );
    }

    public static function getDependencies(): array
    {
        return [];
    }

    public function getAliases(): array
    {
        return [];
    }
}

Our Custom attribute code is custom_category_field and the attribute title is Category Custom field and displayed inside the General Information group.

Now we need to define our custom attribute field to category_form.xml

Path: app/code/Rbj/CategoryAttribute/view/adminhtml/ui_component/category_form.xml

<?xml version="1.0" ?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
	<fieldset name="general">
		<field name="custom_category_field">
			<argument name="data" xsi:type="array">
				<item name="config" xsi:type="array">
					<item name="required" xsi:type="boolean">true</item>
					<item name="validation" xsi:type="array">
						<item name="required-entry" xsi:type="boolean">true</item>
					</item>
					<item name="sortOrder" xsi:type="number">100</item>
					<item name="dataType" xsi:type="string">string</item>
					<item name="formElement" xsi:type="string">input</item>
					<item name="label" translate="true" xsi:type="string">Category custom field</item>
				</item>
			</argument>
		</field>
	</fieldset>
</form>

We have set our custom attribute in the General field set to display our attribute in the General Group of a category page.

Now Run the Setup Upgrade command to install our module in Magento.

Using the Command line, Go to the Magento instance where you have installed Magento, Open Command Line,

php bin/magento setup:upgrade
php bin/magento cache:flush
php bin/magento indexer:reindex
Category attribute
Custom Category attribute

In front, You can get the value of the Category attribute by loading the category object and calling the function below,

Load Category data by, Get Category data by category id

$getCategory = CATEGORY_OBJECT;
echo $getCategory->getCustomCategoryField();