Migrating Your Data from D7 to D10: Applying Drupal recipes to add media types Migrations How-To: #21

Series Overview & ToC | Previous Article | Next Article – coming soon!


First, we will apply a recipe to use images as media entities. From the Drupal 10 folder in your host machine, run the following command:

Drupal recipes

To answer the question posed at the start of this section, it is ok to use recipes when they can be cleanly applied. If subsequent migrations might overwrite configuration elements created by the recipes, make sure the new configuration is truly what you want. If we export and commit configuration changes after every step, git should show us if anything was overridden. Keep in eye on functionality that did not exist in Drupal 7 and could be lost. That should not stop you from using the migration. If anything, manually apply the configuration that was overwritten by the migration.
It depends on your project requirements and the desired content model.
Drupal Core provides a built-in script for applying recipes. Starting with Drush 13, a recipe command is available. When executed from a Drupal 10 docroot, any of these commands can be used to apply a recipe:
Recipes verify that included configuration does not exist or that existing configuration matches the recipe definition exactly. This check is also performed for dependent recipes.

Applying a Drupal recipe

Note: As of Drupal 10.4, recipes can opt out of strict comparisons with existing config. At the time of publishing, a strict comparison is still the default. Changing to making the configuration comparison lenient by default is being discussed in this issue.
In the case of existing configuration, the check is based on machine names. Any variation will prevent the recipe from applying. For example, the image_media_type recipe depends on the large image style. If we update its label from Large (480×480) to Large 480×480 px, the following error will be triggered when trying to apply the recipe:
php core/scripts/drupal recipe /path/to/recipe_folder
drush recipe /path/to/recipe_folder

With one recipe applied, we will now do another that will allow YouTube videos to be embedded. From the Drupal 10 folder in your host machine, run the following command:

Manage Form Display page
ddev drush recipe core/recipes/remote_video_media_type

In ConfigConfigurator.php line 47:

The configuration 'image.style.large' exists already and does not match the recipe's configuration

Today, we’ve covered the basics of the Recipes API, how to apply recipes, and used them for creating media types. In our upcoming articles, we’ll walk through migrating user roles, permissions, and text and input formats to your new Drupal 10 site.
If you have custom image styles, use the upgrade_d7_image_styles migration from the ref_migrations folder. In this case, the image style migration needs to happen after applying the image_media_type recipe. Otherwise, updates to existing image styles will make the configuration validation fail and the recipe would not be applied. While this might seem like a chicken and egg problem, good planning goes a long way into determining the correct order to apply recipes, migrate configuration, and do manual configuration changes.

  1. In the Article content type, add a media reference field to images.
  2. In the Venue content type, add a media reference field to images.
  3. In the Session content type, add a media reference field to remote videos. Add this field to the Resources group.

With media types already created, we are going to manually add media reference fields where appropriate. Per the site audit document referenced in article 3, these are the fields to add:

Troubleshooting recipe application

For the sake of the example, consider image styles. Drupal Core provides a migration for image styles from Drupal 7. If we were to use it, the migration will overwrite any image style to match its Drupal 7 definition. In the case of Core image styles, Drupal 10 uses a WebP converter. That feature did not exist before. Since we are not customizing the Core image styles, and we do not have any custom one, for our example project it is better not to migrate image styles. That way, we take advantage of the optimizations that come with WebP in Drupal 10.
Technical note: Recipes are a first-class Composer project type: drupal-recipe. They can be required as any other Composer package.
This is a site building exercise readers should be able to do on their own. Refer to the code repository for the final configuration.
Take a look at the core/recipes folder in Drupal 10’s docroot to better understand the anatomy of a recipe. Each one is contained in a folder with a required recipe.yml file. They can optionally contain config and content folders to import configuration and content respectively. We could certainly write a whole series on Drupal recipes, but for now we are going to focus on what is applicable to our example project.
These changes required adding new configuration to the site. Remember to export and commit the changes as with any other configuration change. If the recipe failed to apply, refer to the troubleshooting section below.

Should we use recipes in migration projects?

Even so, put on your site builder hat as we take a deeper look at the implications of using these recipes.
Drupal recipes can validate that configuration elements are in a known state before the recipe is applied. Once a recipe is applied, the imported configuration is handled by the site itself. Any updates should follow standard configuration management practices.
Technical note: Most source plugins for upgrading from Drupal 7 connect directly to the database to fetch data. Drupal 7 allowed some configuration to be defined in code, either by modules or features. When that configuration is in its default state, only the code representation exists. The database would not hold a reference to it. That is the case for the image styles in our example. Checking the status of the upgrade_d7_image_styles reveals there are no records to migrate, but we know that image styles do exist in Drupal 7. Those present only exist in code. For them to exist in the database, you would need to overwrite them. This also happens with views, field groups, and other configurations that can be represented in code. Take this into account if a migration reports no records to migrate or the total count is lower than expected.
Remember that recipes are meant to be starting points. You can install a site from recipes. When there is no existing configuration, no conflicts can arise. That being said, applying recipes on existing sites is a valid and useful feature. In addition to those provided by Core, there are contributed recipes that you can use on your projects today.
Image by Hans from Pixabay
ddev drush recipe core/recipes/image_media_type

We executed the last field-related migrations in the previous article, but we are not done with field configuration yet. Back in article 17, we used the Migrate Skip Fields module to prevent the automatic migration from importing image and YouTube fields. Today, we are going to use Drupal recipes to create media types and manually add media reference fields where needed.
In our case, our Drupal 7 project did not use the Media module, but we still wanted to use media entities in Drupal 10. Recipes are available for creating media types modeled after the standard installation profile. No need to reinvent the wheel here!
Our example Drupal 7 project is arguably very simple. It is based on the standard installation profile and there are not many customizations. No custom image styles or text formats, nor changes to those provided out of the box. Only one custom role (Editor) and no WYSIWYG configuration. We could definitely use many Core recipes modeled after the standard installation profile, but should we?


The Recipes API,introduced in Drupal 10.3, allows installing modules and themes, importing configuration and content, and altering existing configuration. Recipes can also depend on other recipes, making them composable and highly flexible. Another benefit is the potential to replace installation profiles. This not only saves time but can bring consistency across different projects. In fact, Core’s standard installation profile was replicated as a set of recipes. We are going to use a couple of those recipes to add media types to our Drupal 10 project.

Similar Posts