Defining configuration in .schema.ymlfor Drupal 8 , 9 , 10 , and 11

Last updated :  

Think of a config schema as the label on a shipping box: it doesn't hold anything itself, but it tells everyone handling the box — customs, the warehouse, the delivery driver — exactly what's inside and what shape to expect. Without that label, someone has to open the box and guess. That's exactly the problem a .schema.yml file solves for your module's configuration: it describes the shape of your config data so Drupal (and every tool that touches it — the Configuration Synchronization UI, the translation system, `drush config:export`) knows what it's looking at without guessing.

What you'll learn in this lesson

  • Why an untyped, unschematized config value is a real source of bugs, not just a missing nicety
  • How to write a .schema.yml file for a module's settings
  • The handful of built-in types you'll reach for constantly: string, label, boolean, mapping, sequence
  • How schema keys line up exactly with the keys in your actual config YAML

A running example: a weather module's settings

Say you're building a module that shows a weather widget, and it needs two settings: an API key for the weather service, and a default location to show when no location is specified. Those two settings need a schema file at config/schema/weather_module.schema.yml:

weather_module.settings:
  type: config_object
  label: 'Weather module settings'
  mapping:
    api_key:
      type: string
      label: 'API key'
    default_location:
      type: string
      label: 'Default location'

The top-level key, weather_module.settings, must match the config object's own name exactly — that's how Drupal knows this schema block describes that specific piece of config. type: config_object is the base type for simple module-wide settings (as opposed to config_entity, which you'd use for something with many instances, like a content type). Everything under mapping corresponds key-for-key to what will actually be saved in config/install/weather_module.settings.yml.

The types that show up constantly

  • string — plain text, not translatable. Use this for machine values like an API key or a slug.
  • label — behaves like a string but is marked translatable, for anything a site visitor would actually read.
  • boolean — a real PHP true/false. Leave this out for a yes/no setting and Drupal hands you the raw string 'false' instead — and in PHP, the string 'false' is truthy. This is the single most common config-schema mistake.
  • mapping — a fixed set of named keys, each with its own type (what you see above).
  • sequence — an ordered list where every item shares the same type, for something like a list of allowed location codes.
Real Examples module reference: the Drupal Examples project's config_entity_example module ships a genuine schema at config/schema/config_entity_example.schema.yml — it types a neural_system boolean exactly the way described above, and is worth reading end to end once you've got the basic shape down.

Quick check: you add a new units setting (metric or imperial) to the weather module's settings form and save it, but forget to add it to the schema's mapping. What actually happens? (Answer: it still saves to the database — schema isn't enforced at write time — but the Configuration Synchronization UI and any strict config-schema test suite will flag it as untyped, and if it's meant to be translatable, it silently won't be. The bug is invisible until someone goes looking for it.)

Key takeaways

  • A schema file's top-level key must exactly match the config object's own name.
  • type: config_object is for module-wide settings; type: config_entity is for entity types with many instances.
  • Every key you actually save in your config YAML needs a matching entry under mapping — an omitted key isn't a hard error, but it breaks translation and schema validation silently.
  • Always type booleans explicitly — an untyped boolean comes back as the string 'false', which PHP treats as truthy.

Coming up next

Now that the weather module's settings have a schema, the next lesson shows how to actually write values into that config object from PHP — using config.factory to save the API key and default location a site builder enters into a settings form.