Hello Magento Friends,
In Magento 2, configuration fields are used to establish admin options that can be customized for modules and extensions. One of the more common use cases is to allow an admin to add on configuration values dynamically, e.g., a list of custom links, fields, or labels.

The common issue developers run into is that the existing values in the dynamically added fields will not be retained when an extension is enabled or disabled. In the worst-case scenario, the data does not persist, and the added rows disappear altogether, which is more than frustrating for admin users!
So, let’s understand how to store the value of dynamic add field in the system configuration.
Steps to Store Existing Value of Dynamic Add Configuration Field in Magento 2:
Step 1: Create a system.xml file at the given path
app/code/Vendor/Extension/etc/frontend/system.xml
Now add the following code:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Magento/Backend/etc/system_file.xsd">
<system>
<tab id="tab_id" translate="label" sortOrder="100" class="logo">
<label><![CDATA[]]></label>
</tab>
<section id="section_id" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<tab>Tab</tab>
<label>Label</label>
<resource>Vendor_Extension::titleconfig</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Configuration</label>
<field id="enable" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="extension" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Add Lable</label>
<backend_model>Vendor\Extension\Block\Adminhtml\Config\Backend\Fileextension</backend_model>
<frontend_model>Vendor\Extension\Block\Adminhtml\Fileextension</frontend_model>
<depends>
<field id="section_id/general/enable">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
Step 2: Create a Fileextension.php file at the given path
app/code/Vendor/Extension/Block/Adminhtml/Config/Backend/Fileextension.php
Now add the code as follows:
<?php
namespace Vendor\Extension\Block\Adminhtml;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
class Fileextension extends AbstractFieldArray
{
protected function _prepareToRender()
{
$this->addColumn(
'Extensions',
[
'label' => __('Lable'),
'size' => '200px'
]
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add');
}
}
Step 3: Create a Fileextension.php file at the given path
app/code/Vendor/Extension/Block/Adminhtml/Fileextensio.php
Now add the code as follows:
<?php
namespace Vendor\Extension\Block\Adminhtml\Config\Backend;
use Magento\Framework\App\Cache\TypeListInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Config\Value as ConfigValue;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Magento\Framework\Serialize\SerializerInterface;
use Vendor\Extension\Helper\Data;
class Fileextension extends ConfigValue
{
protected $serializer;
protected $helper;
public function __construct(
SerializerInterface $serializer,
Context $context,
Registry $registry,
ScopeConfigInterface $config,
TypeListInterface $cacheTypeList,
Data $helper,
?AbstractResource $resource = null,
?AbstractDb $resourceCollection = null,
array $data = []
) {
$this->serializer = $serializer;
$this->helper = $helper;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
public function beforeSave()
{
$value = $this->getValue();
if($this->helper->isEnabled()){
if ($value === null || (is_array($value) && count($value) === 1 && isset($value['__empty'])))
{
$this->setValue($this->getOldValue());
return parent::beforeSave();
}
}
unset($value['__empty']);
$encodedValue = $this->serializer->serialize($value);
$this->setValue($encodedValue);
}
protected function _afterLoad()
{
$value = $this->getValue();
if($value) {
$decodedValue = $this->serializer->unserialize($value);
$this->setValue($decodedValue);
}
}
}
Step 4: Create a Data.php file at the given path
app/code/Vendor/Extension/Helper/Data
Now add the code as follows:
<?php
namespace Vendor\Extension\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\App\Helper\Context;
class Data extends AbstractFieldArray
{
const ENABLED = 'section_id/general/enable';
public function __construct(
Context $context
) {
parent::__construct($context);
}
public function isEnabled($storeid = NULL)
{
return $this->scopeConfig->getValue(self::ENABLED, ScopeInterface::SCOPE_STORE,$storeid);
}
}
Conclusion:
This way, you can store existing dynamic add configuration field values in Magento 2. Let us know in the comments how you use dynamic fields in your Magento projects.

Happy Coding!