Use Drupal’s Config Actions API to Spice Up Your Recipes
The evolution of Drupal recipes has sparked new and powerful ways to manage Drupal configuration. With the introduction of the Config Actions API, developers can now create custom config actions to be used inside recipes, allowing for more dynamic ways to alter config entities. It’s like following a pizza recipe but substituting your own sauce: it opens you up to a wide range of customizations. I’ve been playing with config actions in my own team’s dev work with great success.
In this article, I’ll explore what config actions are, how to use them in a recipe, and how to create your own when your recipe needs an extra kick.
What are config actions and recipes?
Recipes are a new feature in Drupal 10.3 and 11+ that automate the process of installing and configuring modules and themes. They can be applied to assist with new site setups or to add features to existing sites. Recipe authors define YAML-based instructions that enable modules, set permissions, configure fields, create content, and more. They are intended to be reusable with the same predictable results every time they are applied.
Config actions let you update parts of configuration without replacing the whole config object. For example, you can use the config action setRequired on field.field.page.body to make the Basic Page’s Body field required, or use grantPermission to grant a permission to a specified role. Think of config actions as methods you can call from YAML that make a change to the config entity. They power many of the operations inside recipes.
Using existing config actions in recipes
set — The most basic way to set a single value in a config entity.
config:
actions:
pizza_newsletter.config:
set:
property: email_title
value: This Week’s Pizza RecipessetMultiple — The plural form of set, this config action sets multiple values in one go.
config:
actions:
pizza_newsletter.config:
setMultiple:
-
property: from_email
value: ${from_email}
-
property: cc_email
value: ${cc_email}In this example, I’m using ${from_email} and ${cc_email} as input variables, which you can learn more about in the official recipe documentation.
simpleConfigUpdate — Set config properties in the same format as a config file. Try to minimize use of simpleConfigUpdate as it’s expected to be deprecated in the future.
config:
actions:
pizza_newsletter.config:
simpleConfigUpdate:
email_title: This Week’s Pizza Recipes
from_email: ${from_email}
cc_email: ${cc_email}Those are just a few basic examples to demonstrate how config actions are used. Find a full list of actions in the official Drupal Recipes documentation.
Creating a config action plugin
When existing config actions don’t do what you need, you can create your own actions using the Config Action API. There are two ways to accomplish this: with a plugin class or with an Action Method attribute.
To create a config action with a plugin class, implement the ConfigActionPluginInterface like in this example:
<?php
namespace Drupal\food_newsletter_module\Plugin\ConfigAction;
use Drupal\Core\Config\Action\ConfigActionPluginInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Config\Action\Attribute\ConfigAction;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Set the title for newsletter emails.
*/
#[ConfigAction(
id: 'setNewsletterTitle',
admin_label: new TranslatableMarkup('Set Newsletter Title'),
entity_types: ['newsletter'],
)]
final class SetNewsletterTitle implements ConfigActionPluginInterface, ContainerFactoryPluginInterface {
...
}Here we’re creating a config action called setNewsletterTitle that works for newsletter config entities. It accepts frequency, food, and chef as titles and builds a string that will be used for newsletter email titles.
config:
actions:
newsletter.type.pizza:
setNewsletterTitle:
frequency: weekly
food: pizza
chef: DonatelloThis would set the newsletter title to Weekly Pizza Newsletter by Donatello.
Creating a config action method
Another way to create a config action is with an Action Method attribute, which is especially useful if you already have a method in a config entity that you’d like to turn into a config action.
<?php
namespace Drupal\food_newsletter_module;
use Drupal\Core\Config\Action\Attribute\ActionMethod;
use Drupal\Core\Config\Entity\ConfigEntityBase;
class NewsletterConfigEntity extends ConfigEntityBase {
#[ActionMethod(adminLabel: new TranslatableMarkup('Set CC Email'), pluralize: 'setCcEmails')]
public function setCcEmail($email): void {
...
}
}config:
actions:
pizza_newsletter.config:
setCcEmail:
email: Donatello@ninjaturtle.pizzaconfig:
actions:
pizza_newsletter.config:
setCcEmails:
-
email: ${cc_email_1}
-
email: ${cc_email_2}\Drupal::service('plugin.manager.config_action')
->applyAction("setCcEmail", "pizza_newsletter.config", ['email' => 'Donatello@ninjaturtle.pizza']);Developer challenge
The Config Actions API is a powerful addition to Drupal’s configuration management toolkit. When combined with recipes, it enables powerful possibilities for recipe applications. Best practices dictate that recipes create predictable and repeatable outcomes, so keep that in mind when contributing recipes.
If you or your organization maintain contrib modules, chances are they include configuration entities—like those in a config form. Many of these settings need more than a simple setter; they often require value validation, string processing, or other specialized data handling. For your benefit, and for the sites that rely on your modules, consider adding config actions so your configuration entities can be updated correctly as part of a recipe. Before long, this will likely become standard practice—so put in the effort now, and your future self (and your users) will thank you.
Image Attribution Disclaimer: At The Drop Times (TDT), we are committed to properly crediting photographers whose images appear in our content. Many of the images we use come from event organizers, interviewees, or publicly shared galleries under CC BY-SA licenses. However, some images may come from personal collections where metadata is lost, making proper attribution challenging.
Our purpose in using these images is to highlight Drupal, its events, and its contributors—not for commercial gain. If you recognize an image on our platform that is uncredited or incorrectly attributed, we encourage you to reach out to us at #thedroptimes channel on Drupal Slack.
We value the work of visual storytellers and appreciate your help in ensuring fair attribution. Thank you for supporting open-source collaboration!

