HowTo: Magento 2 Add a field to the product edit form


Adding a field to the product edit form in the admin is one of those things that feels harder than it should the first time, because the form is a Ui Component and not a plain layout. Once you know where to hook in, it is just a bit of XML.

There are two common scenarios. If the field maps to a real product attribute, the easiest path is to create the EAV attribute and it will show up on its own. But when you need a field that is not a standard attribute, or you want to place it in a specific fieldset, you extend the product_form Ui Component directly. That is the case I will cover.

This post assumes that there is already a custom module created in app/code/Vendor/Module. If you need to know how to create a custom module, look at How to create a custom module for Magento 2.

Extend the product_form component

Magento merges any product_form.xml it finds under view/adminhtml/ui_component/, so we do not copy the core file, we only declare the piece we want to add.

xml
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/view/adminhtml/ui_component/product_form.xml -->
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="product-details">
        <field name="my_custom_field" sortOrder="200" formElement="input">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" translate="true" xsi:type="string">My Custom Field</item>
                    <item name="source" xsi:type="string">product</item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

That drops a text input into the existing product-details fieldset. Swap formElement for select, checkbox, textarea, etc. as needed.

Persisting the value

If my_custom_field is a real product attribute, Magento saves it for you and there is nothing else to do. If it is not, you populate the form with a data provider modifier and save it with a plugin/observer on the product save. For the vast majority of cases, though, creating the attribute first is the simpler, cleaner route.

Notice: Deploy the admin static content (bin/magento setup:static-content:deploy -a adminhtml in production) and flush the cache, otherwise the form keeps rendering the cached layout and you will swear your field is missing.

Hope this helps.

If you have any question or know a better way to achieve this, feel free to share in the comments below.