How to add CMS Page Programmatically using Patch Data in Magento 2?

From Magento 2.3, Core modules use the declarative schema approach rather than setup upgrade scripts. This is the new recommended approach for Magento versions 2.3 and upper version.

All the InstallData and UpgrageData will be replaced by Data Patch Versioning.

Now you have to create Setup/Patch/Data folder and create the class file for create/update attribute or add sample data in Magento.

The new module is simply residing in the app/code folder of Magento instance.

Just Create Folder under the app/code,
For example, We kept Packagename as Rbj and Modulename as CmsPage.

You can keep any name for Packagename/Modulename. In our demo, we have kept Packagename_Modulename as Rbj_CmsPage.

Now start with basic module creation, Registration.php file is to register our module.

Create a registration.php file,
Full Path,  app/code/Rbj/CmsPage/registration.php,


Create module.xml file,

<?xml version="1.0" ?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Rbj_CmsPage">
            <module name="Magento_Cms"/>

You don’t need to specify the setup_version and schema_version in a module.xml file.

Create a Patch file, Our module that contains the name is AddNewCmsPage.php

Path: app/code/Rbj/CmsPage/Setup/Patch/Data/AddNewCmsPage.php

 * @author Rakesh Jesadiya
 * @package Rbj_CmsPage

namespace Rbj\CmsPage\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Cms\Model\PageFactory;

 * Class AddNewCmsPage
 * @package Rbj\CmsPage\Setup\Patch\Data
class AddNewCmsPage implements DataPatchInterface, PatchVersionInterface
     * @var ModuleDataSetupInterface
    private $moduleDataSetup;

     * @var PageFactory
    private $pageFactory;

     * AddNewCmsPage constructor.
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param PageFactory $pageFactory
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        PageFactory $pageFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->pageFactory = $pageFactory;

     * {@inheritdoc}
    public function apply()
        $pageData = [
            'title' => 'Custom Page Title',
            'page_layout' => '1column',
            'meta_keywords' => 'Page keywords',
            'meta_description' => 'Page description',
            'identifier' => 'custom-page',
            'content_heading' => 'Custom Page',
            'content' => '<div class="main-cms-content">Content goes here for My cms page. CMS Page create using Programmatically</div>',
            'layout_update_xml' => '',
            'url_key' => 'custom-page',
            'is_active' => 1,
            'stores' => [0], // store_id comma separated
            'sort_order' => 0

        /* Save CMS Page logic */

     * {@inheritdoc}
    public static function getDependencies()
        return [];

     * {@inheritdoc}
    public static function getVersion()
        return '2.0.0';

     * {@inheritdoc}
    public function getAliases()
        return [];

The DataPatchInterface expects the implementation of three functions: apply(), getDependencies() and getAliases().

The PatchVersionInterface expects the implementation of one functions: getVersion().

apply() function is used to define your core logic for install/upgrade data to the database.
getAliases()  which defines aliases for this patch class.
getDependencies() function expects an array of strings containing class names of dependencies.
getVersion() function, we can return a string with a version number of Patch.

The apply function is where we will create our CMS Page programmatically. You can check the function in code and all the fields are self-explanatory.

For installing our module in Magento 2,  We need to run the command using SSH,  Login with SSH and go to your project root path where Magento is installed,
Run below command,

php bin/magento setup:upgrade
php bin/magento cache:flush

For all patches which are successfully executed,

Magento inserts a record into the patch_list database table with the value of the patch_name field being the value of our Data patch full class.

You can check the CMS Page from the admin panel. Go To Admin Panel, Click On Content -> Elements -> Pages

Check Get CMS Page collection using GraphQl Magento 2.