component_field
Component Field Module
Overview
This module provides auto-discovery of Drupal Single Directory Components (SDC) from your theme, allowing content editors to easily add and configure these components through the node editing interface.
Features
Auto-Discovery: Automatically scans your theme for SDC components
Props Introspection: Parses component YAML schemas to extract prop definitions and types
Dynamic Forms: Generates configuration forms based on discovered component props
Live Preview: Shows component preview while editing
Rich Text Support: Full support for text_format fields with CKEditor5
Cache-Aware: Automatically detects component changes
Admin Interface: Manage and refresh discovered components
Zero Dependencies: Works with core Drupal SDC system
Installation
1. Place this module in web/modules/custom/component_field/
2. Enable the module: drush en component_field
3. Visit /admin/structure/component-field to view discovered components
Component Discovery
The module searches for SDC components in these directories within your active theme:
• components/
• src/components/
Component Requirements
Components are discovered if they:
1. Follow the standard Drupal SDC structure
2. Have a .component.yml schema file
3. Are located in component directories within your theme
4. Have valid YAML schema definitions
Supported Prop Types
The module can parse and generate forms for:
String: Text inputs, select dropdowns for enums
Text: Rich text fields with CKEditor5 support (HTML, Markdown, Raw HTML)
Number/Integer: Number inputs with min/max validation
Boolean: Checkboxes
Array: JSON textarea inputs with validation
Object: JSON object inputs with validation
Entity Reference: Entity autocomplete, media library widgets
Enums: Select dropdowns for predefined values
Component Schema Example
# my-component.component.yml
$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
name: My Component
description: 'A sample component with various prop types'
props:
type: object
properties:
title:
type: string
title: 'Component Title'
description: 'The main heading for the component'
content:
type: text
format: html
title: 'Rich Content'
description: 'HTML content with CKEditor5 support'
variant:
type: string
enum: ['primary', 'secondary', 'tertiary']
title: 'Style Variant'
default: 'primary'
enabled:
type: boolean
title: 'Enable Component'
default: true
featured_image:
type: entity_reference
target_type: media
target_bundles: ['image']
title: 'Featured Image'
Usage
Adding Components to Content
1. Edit any page or article node
2. In the "Component Field" field, click "Add another item"
3. Select a component from the dropdown
4. Configure the component properties
5. See live preview as you type
6. Save the node
Admin Management
Visit /admin/structure/component-field to:
• View all discovered components
• See component source files and modification dates
• Refresh component discovery
• View prop counts per component
Refreshing Discovery
Components are cached for performance. Refresh discovery when:
• You add new components
• You modify existing component schemas
• Components aren't appearing correctly
Refresh methods:
1. Admin UI: /admin/structure/component-field → "Refresh Components"
2. Node form: "Refresh Components" button in Component Field field
3. Drush: drush cr (clears all caches)
4. Programmatically: \Drupal::service('component_field.discovery')->clearCache()
Theme Integration
Basic Integration
The module outputs components using Drupal's standard SDC system:
{# In your theme #}
{{ content.field_component_field }}
Advanced Integration
For custom rendering, override the theme templates:
{# templates/component-field-dynamic.html.twig #}
<div class="my-component-wrapper" data-component="{{ component_type }}">
{# Custom rendering logic #}
{% include '@myTheme/components/' ~ component_name ~ '/' ~ component_name ~ '.twig' with configuration %}
</div>
Component Templates
Create standard SDC component templates:
{# components/my-component/my-component.twig #}
<div class="my-component my-component--{{ variant }}">
{% if title %}
<h3 class="my-component__title">{{ title }}</h3>
{% endif %}
{% if content %}
<div class="my-component__content">{{ content|raw }}</div>
{% endif %}
</div>
API
Services
• component_field.discovery: Component discovery service
• component_field.props_parser: Props parsing service (legacy, now uses YAML)
Hooks
The module provides standard Drupal hooks:
• hook_theme(): Custom theme implementations
• hook_library_info_build(): Dynamic library generation
• hook_form_alter(): Form modifications with CKEditor5 support
Cache Tags
• component_field: Cache tag for all component data
Performance
• Components are cached until manually refreshed
• Discovery only runs on cache miss
• File modification times tracked for cache invalidation
• Minimal overhead in production
Troubleshooting
No Components Found
1. Check theme component directories exist (components/, src/components/)
2. Verify components have .component.yml schema files
3. Ensure YAML schemas are valid
4. Check file permissions
Props Not Detected
1. Verify YAML schema syntax in .component.yml
2. Check props.properties structure
3. Ensure proper prop type definitions
4. Review parser logs at /admin/reports/dblog
Preview Not Working
1. Check JavaScript console for errors
2. Verify widget JavaScript is loading
3. Ensure proper component configuration
4. Check Drupal behaviors initialization
CKEditor5 Issues in Rich Text Fields
1. Clear caches after adding text_format fields
2. Check that CKEditor5 module is enabled
3. Verify text format permissions
4. Review browser console for JavaScript errors
Extending
Custom Prop Types
Add support for custom prop types by extending the discovery service:
// In your custom module
function mymodule_component_field_prop_element_alter(&$element, $prop_info) {
if ($prop_info['type'] === 'custom_type') {
$element['#type'] = 'my_custom_widget';
}
}
Custom Discovery Paths
Modify discovery paths by extending the service:
# In your services.yml
services:
component_field.discovery:
class: Drupal\mymodule\Service\CustomComponentDiscovery
parent: component_field.discovery
Search Integration
The module includes Search API integration:
• Automatically extracts searchable content from component configurations
• Indexes rich text fields and entity references
• Supports custom content extraction for specialized components
Requirements
• Drupal 10.4+ or 11.x
• Single Directory Components (SDC) enabled (core in Drupal 10.1+)
• CKEditor5 module (for rich text support)
Security
• All user input is sanitized
• JSON configuration validated
• Component paths restricted to theme directories
• Admin permissions required for management
• Rich text content processed through Drupal's filter system
Companion modules
Component field is a core module that works with the following modules to extend the functionality.
A theme is being developed based on MUI and heavy with SDCs to test these modules - see MUI Base for more details.
License
GPL-2.0-or-later