Defining Config Schema for a Settings Formfor Drupal 8 , 9 , 10 , and 11

Last updated :  

A config form's buildForm() can save whatever keys you tell it to — Drupal's form-building code has no idea what "correct" looks like for your data. A config schema is the missing rulebook: a YAML file that says, for every key your config form saves, exactly what data type it must be and whether it's translatable. Without one, every value silently arrives as a raw, untyped string, and your config is invisible to translation and config-inspection tooling.

What you'll learn in this lesson

  • Where schema files live and how Drupal discovers them automatically
  • The config_object base type used for simple settings config
  • Why the text type matters specifically because it's translatable by default
  • How an unschematized key silently breaks translation and type safety

A real schema file

config_simple_example.settings:
  # A config_object is a configuration object which can store fields.
  # You have to map all field types the object stores: string, boolean, etc.
  # The "text" field type is special because it's translatable by default.
  # Checkout how to define schema and all available data types in:
  # https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-schemametadata
  type: config_object
  label: 'Example config'
  mapping:
    message:
      type: text
      label: 'Message'

How it works

File location and auto-discovery

Schema files live in a module's config/schema/ directory, named <module_name>.schema.yml. That's the entire registration step — Drupal scans every enabled module for this exact path pattern at bootstrap. Nothing needs declaring in .info.yml, and there's no hook to implement.

The top-level key matches the config object's own name

config_simple_example.settings:

Unlike a config entity schema (which uses a glob pattern like module.type.* to cover many instances), a simple settings object's schema key is the literal, exact name of the one config object it describes — config_simple_example.settings, matching both the form's getEditableConfigNames() value and the actual saved file config_simple_example.settings.yml.

type: config_object

type: config_object

This is the base type for plain settings config — as opposed to config_entity, which you'd use for a config entity type with its own id/uuid/langcode fields. A simple settings object doesn't have those, so config_object is the correct, lighter-weight choice.

mapping: and the text type

mapping:
  message:
    type: text
    label: 'Message'

Every key your config actually stores needs an entry here. message is typed text rather than plain string specifically because text is translatable by default through Drupal's Interface Translation system — appropriate for a longer, user-facing message. A short, non-translatable machine value would instead use string; a translatable short label would use label.

Common beginner mistake: adding a new field to a config form's buildForm() without adding a matching entry to the schema's mapping. The form will still save the value — Drupal doesn't block an unschematized save — but that value stays untyped, untranslatable, and invisible to tools like the Configuration Inspector until you fix the schema.

Quick check: if message were typed string instead of text, what would you lose? (Answer: translatability through the Interface Translation system — string and text store the same kind of value, but only text is translatable by default. You'd need to add explicit translatable: true metadata to get the same behavior with string.)

Key takeaways

  • Schema files go in config/schema/<module_name>.schema.yml and are auto-discovered — no registration step required.
  • Use type: config_object for plain settings; reserve type: config_entity for config entity types with their own id/uuid/langcode.
  • Prefer type: text over type: string for any translatable, user-facing message — it's translatable by default.
  • Every key your form saves needs a matching entry under mapping, or it silently stays untyped and untranslatable.

Coming up next

With the shape of the data declared, the next lesson, "Saving Configuration Data," covers the other half: how submitForm() actually writes the form's values back into this schema-typed config object.