Creating a single-directory component

Last updated on
27 March 2025

This documentation needs review. See "Help improve this page" in the sidebar.

A single-directory component meets the following criteria

  1. It must be within your theme or module’s components/ directory. Note that it can be nested within subdirectories (for example components/atoms/, components/molecules/, etc)
  2. It must contain the following files (where my-component is the name of your component)
    1. my-component.component.yml - this contains the definition of the component including name, status, schema, etc
    2. my-component.twig - this is the normal Twig file that contains markup as well as logic such as conditionals and loops to interact with the variables defined within the YML. (Note that the filename extension should be .twig and not .html.twig, as regularly seen in other theme template files.)
  3. It may contain other files such as CSS, JavaScript, source files (Sass, etc), images, documentation, etc

Note about creating the schema

Creating a schema within your my-component.component.yml is mandatory for modules, but optional for themes. However it’s highly recommended to do so. Benefits include:

  • Only components that have schemas can override other components.
  • Using schemas will illuminate problems with your components earlier.
  • Schemas will enable contributed modules (and maybe eventually core) to automatically generate forms to populate the component.

Note you can force all components within your theme to require schemas by adding the following to your themename.info.yml.

enforce_prop_schemas: true

To create your first single-directory component, follow these steps

  1. Create a new directory called components/ in your theme or module’s directory.
  2. Create a new directory within your theme’s components/ directory with the name of your new component (ex my-component) .
  3. Create two new files within this directory
    1. A twig file with the name of your component (ex my-component.twig)
    2. A YAML file with the *.component.yml extension that is named with your component (ex my-component.component.yml). View (or copy and paste) the example annotated YAML file to get started.
  4. For the CSS and JavaScript to automatically load, they must be named after the component (ex. my-component.css, and my-component.js).
  5. You can load additional styles, scripts, and dependencies using the libraryOverrides key within your component’s YML file if necessary.

The final directory structure will look something like this

|- my-theme
    |- components
        |- my-component
            |- my-component.twig (required)
            |- my-component.component.yml (required)
            |- README.md
            |- thumbnail.png
            |- my-component.js
            |- my-component.css
            |- assets
                |- img1.png

Component data validation

During development time the data provided to the props can be validated against the schema. This will give developers an early warning that something is off.

For schema to be validated, two conditions must be met:

  1. The justinrainbow/json-schema composer package must be installed. This can easily be installed via drupal/core-dev:
    composer require drupal/core-dev --dev
  2. Assertions must be enabled. If assertions are disabled within your local environment, you can add the following to your settings.php to enable them:
    ini_set('zend.assertions', 1);

Writing the schema for your components is mandatory if the component lives in a module or a theme that contains enforce_prop_schemas: true in its info file.

Note that enforce_prop_schemas: false only applies to the absence of a schema definition for the entire component. Even with this setting present, each individual element of the schema will be validated individually.

Overriding components provided by other modules or themes

Only themes can override components (modules cannot override). For a theme to override a component, use the replaces key within the mytheme.component.yml file.

In addition, both components must have schemas defined within their YML files, and the schemas’ props and slots must match.

The value of the replaces key must refer to the other component using the machine name of the module/theme and the machine name of the component, delimited with a colon (:). In the example below, sdc_theme_test is the name of the theme that contains the component to be replaced, and my-card is the machine name of that component.

replaces: 'sdc_theme_test:my-card'

Manual enablement needed in 10.2.x or earlier

Starting with Drupal 10.3, Single-Directory Components became part of Drupal Core's render system. If you're using Drupal 10.2 or earlier, you must enable the module in Core manually to use this feature.

Help improve this page

Page status: Needs review

You can: