Skip to content

Config Actions List

The following config actions are available in Drupal core.

Also see the Contrib Config Actions List.

All Config Actions by type.

  1. Applicable to all config entity types
  2. cloneAs
  3. create
  4. createIfNotExists
  5. createForEach / createForEachIfNotExists
  6. disable
  7. enable
  8. setStatus
  9. set / setMultiple
  10. setThirdPartySetting(s)
  11. simpleConfigUpdate
  12. Applicable to specific config entity types
  13. add(EntityType) - Workflows
  14. addNavigationBlock
  15. allowLayoutOverrides
  16. addItemToToolbar - CKEditor
  17. setFilterConfig - CKEditor
  18. addToAllBundles - field storage
  19. createCopy
  20. enableLayoutBuilder
  21. disableLayoutBuilder
  22. grantPermission(s)
  23. hideComponent(s)
  24. placeBlockInAdminTheme/placeBlockInDefaultTheme
  25. setComponent(s)
  26. setDefaultValue
  27. setDescription
  28. setLabel
  29. setMessage
  30. setRecipients
  31. setRedirectPath
  32. setRegion
  33. setReply
  34. setRequired
  35. setSettings
  36. setTranslatable
  37. setWeight
  38. Config Entity Wildcards
  39. Adding the same permission(s) to all user roles
  40. Affecting every view display of every content type
  41. Changing settings on every instance of a field
  42. Creating a view display (i.e., enabling a view mode) for every content type
  43. Overriding a base field for every media type

Config Actions sorted by entity type.

block.block.* - placeBlockInAdminTheme/placeBlockInDefaultTheme - setRegion - setWeight

core.entity_form_display.*.*.* core.entity_view_display.*.*.* - hideComponent(s) - setComponent(s) - allowLayoutOverrides - enableLayoutBuilder - disableLayoutBuilder

contact.form.* - setMessage - setRecipients - setRedirectPath - setReply - setWeight

editor.editor.* - addItemToToolbar

field.field.*.*.* - setDefaultValue - setDescription - setLabel - setRequired - setSettings - setTranslatable

field.storage.*.* - addToAllBundles - field storage

filter.format.* - setFilterConfig

navigation.block_layout - addNavigationBlock

user.role.* - grantPermission(s)

workflows.workflow.* - add(EntityType)

Applicable to all config entity types

cloneAs

Use the cloneAs config action to create a clone of any config entity with a new ID.

config:
  actions:
    image.style.thumbnail_16x9:
      cloneAs: thumbnail_widescreen

This will create a image.style.thumbnail_widescreen config entity.

If the cloned entity already exists (identified by its ID), it will be left untouched.

If you want to use a wildcard to clone, use the createCopy config action.

create

The create config action can be used to create a config entity. This action will error out if the entity (identified by ID) already exists.

It is not likely to be often useful in recipes on its own as it is preferred to use the /config folder to create config entities.

createIfNotExists

The createIfNotExists config action extends the create config action and can be used to conditionally create a config entity if it does not exist. Existence is determined by it having the same ID.

If your recipe needs a particular config entity to exist (by ID), but does not care about what it contains, use createIfNotExists. This way is best for things like user roles, where you most likely don't care about its label or weight, but probably just want to add some permissions (which you can do with a config action).

If the recipe needs to create a config entity and requires that it look a particular way, putting it in the config directory is the way forward. This way is best for things like fields, which generally must have specific configurations that affect the way data is stored.

In Drupal 10.4+, you can also use config:strict to allow for leniency when comparing config in your recipe to the config in Drupal.

createForEach / createForEachIfNotExists

The createForEach and createForEachIfNotExists config actions are used to loop over bundle config entities to create other config entities that are coupled to those bundles.

These actions are meant to be used with wildcards, and can only work on entities that are bundles of another entity type, such as node types, media types, taxonomy terms, and so forth.

A classic use case is making every content type translatable. This requires creating a language.content_settings.node.TYPE entity for each node type.

config:
  actions:
    node.type.*:
      createForEach:
        language.content_settings.node.%bundle:
          target_entity_type_id: node
          target_bundle: %bundle

In this config action, the %bundle placeholder will be replaced with the ID of the node type being processed. For example, when processing a blog node type, it will create a corresponding language.content_settings.node.blog entity.

Let's say you want to create content settings and an image style for each content type. You can use createForEach to create multiple entities at once:

config:
  actions:
    node.type.*:
      createForEachIfNotExists:
        language.content_settings.node.%bundle:
          target_entity_type_id: node
          target_bundle: %bundle
        image.style.node_%bundle_thumbnail:
          label: 'Thumbnail for %label content'

For a blog content type, this will create both a language.content_settings.node.blog entity and an image.style.node_blog_thumbnail. In the array values (but not the keys) you can use the %label placeholder to insert the human-readable label of the bundle being processed.

disable

Marks any config entity as "disabled". The effect of this varies by config entity type. For example, disabling a view keeps it editable in the administrative UI, but makes it unavailable everywhere else. Works on all config entities.

views.view.files:
  disable: []

enable

Marks any config entity as "enabled". The effect of this varies by the config entity type. Works on all config entities.

views.view.files:
  enable: []

setStatus

Sets the status of the configuration entity. Works on all config entities.

# Enable views.view.latest
config:
  actions:
    views.view.latest:
      setStatus: true

# Disable views.view.latest
config:
  actions:
    views.view.latest:
      setStatus: false

set / setMultiple

Changes a property of a config entity. This is a pretty low-level method and should generally only be used if no dedicated method exists. Works on all config entities.

user.role.authenticated:
  set:
    property_name: label
    value: Logged-in user

setMultiple is the same as set, but accepts multiple property/value pairs.

user.role.authenticated:
  setMultiple:
    - property_name: label
      value: Logged-in user
    - property_name: is_admin
      value: false

setThirdPartySetting(s)

The setThirdPartySetting(s) config actions allows the recipe author to set third-party settings values for any config entity that can carry third-party settings, which at the time of this writing includes all config entities. Helpful for modules like Layout Builder and Scheduler that use these settings to provide or change functionality.

Singular:

config:
  actions:
    core.entity_view_display.node.test.full:
      setThirdPartySetting:
        module: layout_builder
        key: enabled
        value: true

To set multiple third-party settings:

config:
  actions:
    core.entity_view_display.node.test.full:
      setThirdPartySettings:
        -
          module: layout_builder
          key: enabled
          value: true
        -
          module: layout_builder
          key: allow_custom
          value: true

simpleConfigUpdate

A globally applicable config action, simpleConfigUpdate, can be used to make updates to any configuration value. Despite its name, this action can be applied to any type of configuration. (There's a @todo in the code questioning whether this is correct.)

Sample usage to update the page.front value in the system.site simple configuration:

actions:
  system.site:
    simpleConfigUpdate:
      page.front: '/node'

The plural version takes the same name as the singular but passes multiple arguments. Example:

actions:
  system.site:
    simpleConfigUpdate:
      page.front: '/node'
      default_langcode: 'es'

Applicable to specific config entity types

These config actions can be applied to specific config entity types.

add(EntityType) - Workflows

If you have an entity type or entity bundle that you want to add to a content moderation workflow, you can use config actions.

config:
  actions:
    workflows.workflow.editorial:
      # Opt only certain content types into moderation.
      addNodeTypes: [page, article]
      # Opt every taxonomy vocabulary into moderation.
      addTaxonomyVocabularies: '*'

The action is dynamic and automatically converts singular entity type plugin IDs, like taxonomy_vocabulary, into plural strings like TaxonomyVocabularies so it will work with custom and additional config entity types. Just "pluralize" the plugin ID, remove any underscores, convert to SentenceCase, and prepend add. For example, the paragraph_type entity type will become addParagraphTypes.

addItemToToolbar - CKEditor

To add a new toolbar item, optionally at a specific position, and optionally replacing the item that's already in that position, use the addItemToToolbar config action.

config:
  actions:
    editor.editor.foo:
      addItemToToolbar:
        item_name: MediaLibrary
        # Specific zero-based position in the toolbar.
        # If not specified, it appends to the end.
        position: 3
        # If there's already something at that position, replace it.
        # For example, replace the Image button with Media library. By default,
        # existing items are left where they are, and the new item is inserted
        # right before them.
        replace: true

addNavigationBlock - navigation

You can add new blocks to Navigation using the addNavigationBlock config .action

config:
  actions:
    navigation.block_layout:
      addNavigationBlock:
        # The position in the navigation the block is going to be added.
        delta: 1
        # The configuration array for the navigation item.
        configuration:
          id: 'navigation_menu:content'
          label: Content From Recipe
          label_display: 1
          provider: navigation
          level: 1
          depth: 2

This action can be only used against the navigation.block_layout config.

allowLayoutOverrides

This action allows you to configure Layout builder overrides on entity view displays config files.

config:
  actions:
    core.entity_view_display.node.*.default:
      allowLayoutOverrides: true/false
See also: enableLayoutBuilder disableLayoutBuilder

addToAllBundles - field storage

If you have a field that you want to add to every content type, but you don't know how many content types there are, or what they're called, there's an addToAllBundles config action that will automatically add a field to every content type.

For example, if you have a field storage called field.storage.node.field_meta_tags, and you want to add it to every content type:

config:
  actions:
    field.storage.node.field_meta_tags:
      addToAllBundles:
        label: Meta tags
        description: Choose your meta tags for this content.

This action works exactly the same way for fields that attach to media types, taxonomy terms, or any other fieldable entity type. You can specify the field's label and user-facing description, and it will be the same for every bundle. At the time of this writing, you cannot change the settings of the new fields; they will be created with their default settings.

By default, the addToAllBundles action will not conflict with fields that already exist. So, for example, if you have field_meta_tags tags on your article content type, but not your page and blog_post content types, the action will add the field to the page and blog_post content types, but the one on article will be left alone. However, if you specify the fail_if_exists flag, an error will occur if the field already exists on any content type:

config:
  actions:
    field.storage.node.field_meta_tags:
      addToAllBundles:
        label: Meta tags
        description: Choose your meta tags for this content.
        # If field_meta_tags already exists on any content type, you'll get an error.
        fail_if_exists: true

Another thing to bear in mind is that this action will add the field to every bundle, but it will NOT make the field visible to editors or users. To do that, you will also need to use the setComponent action of entity view displays and entity form displays. Here, then, is a complete example of adding a field to every content type, and then ensuring it's available to editors and viewers:

config:
  actions:
    field.storage.node.field_byline:
      addToAllBundles:
        label: Byline
        description: The name of the person who wrote this content.
    # Make sure the field is visible on the node edit forms.
    entity_form_display.node.*.default:
      setComponent:
        field_byline:
          type: text_textfield
    # Ensure the field is visible when viewing content.
    entity_view_display.node.*.full:
      setComponent:
        field_byline:
          type: text_default

createCopy

If you want to use a wildcard to clone the entity view or form display for a particular mode of every bundle, you could use the new createCopy action, which only applies to entity view and form displays.

config:
  actions:
    core.entity_view_display.node.*.teaser:
      createCopy: search_result

If you have two content types, page and blog, this will create two entities that are clones of the teaser displays for those content types.

  • core.entity_view_display.node.page.search_result
  • core.entity_view_display.node.blog.search_result

disableLayoutBuilder

This action allows you to disable Layout builder on entity view displays.

config:
  actions:
    core.entity_view_display.node.*.default:
      disableLayoutBuilder: []
See also: allowLayoutOverrides enableLayoutBuilder

enableLayoutBuilder

This action allows you to enable Layout builder on entity view displays.

config:
  actions:
    core.entity_view_display.node.*.default:
      enableLayoutBuilder: []
See also: allowLayoutOverrides disableLayoutBuilder

grantPermission(s)

Used to add permissions to user roles.

Singular:

config:
  actions:
    user.role.editor:
      grantPermission: 'delete any article content'

Multiple:

config:
  actions:
    user.role.editor:
      grantPermissions:
        - 'delete any article content'
        - 'edit any article content'

User roles also have specialized actions that allow you to grant permissions that are specific to a particular bundle -- for example, permissions that are defined per content type, or per media type, such as create page content or edit own image media. If you want to grant one of these permissions for every bundle of an entity type, you can use config actions to do it dynamically.

For example, to grant the ability for a role to edit their own content, for every content type:

config:
  actions:
    user.role.editor:
      grantPermissionsForEachNodeType:
        - 'edit own %bundle content'

The token %bundle is dynamically replaced by the machine name of the bundle.

It also works for media types:

config:
  actions:
    user.role.media_creator:
      grantPermissionsForEachMediaType:
        - 'create %bundle media'
        - 'delete own %bundle media'

And taxonomy vocabularies:

config:
  actions:
    user.role.info_architect:
      grantPermissionsForEachTaxonomyVocabulary:
        - 'create %bundle terms'

Advanced: Any entity type that supports bundles will automatically have actions like this. The name of the action is derived from the machine name (ID) of the bundle entity type. So say that paragraph entities' bundles are defined by paragraph_type entities; this will result in a config action called grantPermissionsForEachParagraphType, which allows you to grant paragraph type-specific permissions to a user role.

hideComponent(s)

Hides a component from an entity view display or entity form display.

core.entity_view_display.node.page.full:
  hideComponent: uid

hideComponents is the same as hideComponent, but hides more than one component.

core.entity_form_display.media.image.default:
  hideComponents:
    - uid
    - path

placeBlockInAdminTheme/placeBlockInDefaultTheme

To allow for flexibility when placing blocks, recipe authors can leverage the placeBlockInDefaultTheme and placeBlockInAdminTheme config actions. These allow for a block to be placed in the site's currently configured default theme (shown to anonymous users) or admin theme (shown on admin pages to users with permission), respectively.

config:
  actions:
    block.block.powered_first_default:
      placeBlockInDefaultTheme:
        id: powered_first
        # The region accepts an array keyed by theme name.
        region:
          bootstrap: footer
          gesso: page_bottom
          olivero: footer_top
        # A fallback used if no match found in the region array.
        default_region: content
        # Place the block before any blocks already in the region.
        position: first
        plugin: system_powered_by_block
    block.block.powered_last_admin:
      placeBlockInAdminTheme:
        id: powered_last
        # The region accepts an array keyed by theme name.
        region:
          gin: pre_content
          claro: content
        # Place the block after any blocks already in the region.
        position: last
        plugin: system_powered_by_block

Note that the region accepts a mapped array to set the preferred region per theme. A default_region can also be provided to act as a fallback, in case the preferred region can't be found in the theme.

Also, the position value can be used to place a block as either the first or last block in the intended region. If provided, a weight value will be calculated to ensure that the block appears at the intended position.

setComponent(s)

To add a field to an entity's view or form displays, you can use setComponent(s).

Singular:

config:
  actions:
    core.entity_view_display.node.article.default:
      setComponent:
        name: field_tags
        options:
          type: entity_reference_label
          label: above
          settings:
            link: true
          third_party_settings: {  }
          weight: 10
          region: content

A pluralized version, adding the configuration for multiple fields:

config:
  actions:
    core.entity_view_display.node.article.default:
      setComponents:
        -
          name: field_tags
          options:
            type: entity_reference_label
            label: above
            settings:
              link: true
            third_party_settings: {  }
            weight: 10
            region: content
        -
          name: field_categories
          options:
            type: entity_reference_label
            label: above
            settings:
              link: true
            third_party_settings: {  }
            weight: 11
            region: content

setDefaultValue

Sets the default value of a field, which can be changed by users when editing content. Exactly what the default value should look like, varies by field type. Works on fields and base field overrides.

field.field.node.page.field_byline:
  setDefaultValue:
    value: "Joe Bag o'Donuts"

setDescription

Changes the user-facing description of a field. Works on fields and base field overrides.

field.field.node.page.field_byline:
  setDescription: 'Enter the name or credit of whoever created this magnificent page.'

setFilterConfig

This action allows you to set a filter for an existing Ckeditor text format.

config:
  import:
    actions:
      filter.format.full_html:
        setFilterConfig:
          instance_id: filter_id
          configuration:
            id: filter_id
            provider: module_name
            status: true
            weight: 0
            settings: { }

setLabel

Changes the human-readable label of a field. Works on fields and base field overrides.

field.field.node.page.field_byline:
  setLabel: 'Byline for this page'

setMessage

Sets the message that a contact form should display to users when they submit the form. Only works on contact forms.

contact.form.feedback:
  setMessage: 'Thanks for telling us how you feel.'

setRecipients

Sets the email addresses that should be notified when a user submits a contact form. Accepts an array of email addresses. Only works on contact forms.

contact.form.feedback:
  setRecipients:
    - king@monarchy.uk
    - chief@example.com

setRedirectPath

Sets the path (URL) where users should be redirected when they submit a contact form. Must start with a slash. Only works on contact forms.

contact.form.feedback:
  setRedirectPath: '/thank-you'

setRegion

Sets the region in which a block should be. Which regions are available depends on which theme the block is in. Only works on blocks.

block.block.olivero_powered:
  setRegion: page_bottom

setReply

Sets a message to be emailed to the person who submitted a contact form. Only works on contact forms.

contact.form.feedback:
  setReply: 'We have received your feedback and will get back to you at some point when the planets align properly.'

setRequired

Sets whether users must enter a value for a field. Works on fields and base field overrides.

field.field.node.page.field_byline:
  setRequired: true

setSettings

Changes field settings. Exactly which settings are available, and what they mean, varies by the field type. Any preexisting settings are added automatically, with the incoming settings taking precedence. Works on fields and base field overrides.

field.field.node.page.field_byline:
  setSettings:
    display_summary: true
    required_summary: true

setTranslatable

Sets whether a field should be translatable in the UI, or not. Works on fields and base field overrides. (Note that most fields are translatable by default.)

field.field.node.page.field_byline:
  setTranslatable: true

setWeight

Blocks:

Sets the weight (position relative to other blocks in the same region of the same theme) of a block. Accepts any number. Works on Blocks.

block.block.olivero_powered:
  setWeight: 39

Contact forms:

Sets the weight of the contact form, relative to other contactforms, in the administrative UI. Accepts a number. Only works on contact forms.

contact.form.feedback:
  setWeight: -50

Config Entity Wildcards

You can use wildcards in your recipe to apply actions to multiple config entities of the same type.

Here are some examples of possible uses:

Adding the same permission(s) to all user roles

actions:
  user.role.*:
    grantPermissions:
      - 'access content'

Affecting every view display of every content type

actions:
  core.entity_view_display.node.*.*:
    setComponent:
      name: field_tags
      options:
        type: entity_reference_label
        label: above
        settings:
          link: true
        third_party_settings: {  }
        weight: 10
        region: content

Changing settings on every instance of a field

actions:
  field.field.media.*.field_tags:
    simpleConfigUpdate:
      foo: bar

Creating a view display (i.e., enabling a view mode) for every content type

actions:
  core.entity_view_display.node.*.foo:
    createIfNotExists:
      # The contents of the view display here...

Overriding a base field for every media type

actions:
  core.base_field_override.media.*.thumbnail:
    createIfNotExists:
      # The contents of the base field override here...

Note that you cannot use wildcards on simple config (such as gin.settings), or all config provided by a specific module. For example, something like node.* to target all config provided by the Node module, won't work.

You also cannot use wildcards on config prefixes. For example, these are all invalid and will raise exceptions:

# Won't hit field.field and field.storage.
field.*.media.foo.field_bar
# Won't hit all configs provided by a project.
node.*.something
# Won't hit config from any module that provides something called a "vocabulary".
*.vocabulary.wat

In other words, you can only put wildcards in the "identifying" parts of a config entity's full name.

This is due to the way config entities relate to the underlying config schema.

Using input tokens as wildcards

As of Drupal 11.1.2 (not in Drupal 10), you can use the input tokens to dynamically target config entities, with certain limitations.

config:
  actions:
    node.type.${content_type}:
      setDescription: 'Changing the description of a user-chosen node type!'

You can only use the tokens in the identifying parts of the config entity ID, for example, a node type's actual machine name, node.type.${content_type}.

Input tokens can also only be used on configuration entity names. The can't be used in simple config names.

config:
  actions:
    # Tokens can't be used to select the entity type.
    ${module_name}.type.foo:
      doSomething: here
    # Tokens can't be used on simple configs.
    system.${config_name}:
      simpleConfigUpdate:
        someKey: some value