SDC Component Format
When to Use
Use this when creating a Canvas-compatible component using Drupal's Single Directory Component (SDC) system. This produces a server-side-rendered Twig component with Drupal field widget integration in the Canvas editor.
Decision
| Prop type | YAML definition | Canvas editor widget |
|---|---|---|
| Plain text | type: string |
Single-line text input |
| Rich text (block) | type: string + contentMediaType: text/html + x-formatting-context: block |
CKEditor block editor |
| Rich text (inline) | type: string + contentMediaType: text/html + x-formatting-context: inline |
CKEditor inline editor |
| Image | type: object + $ref: 'json-schema-definitions://canvas.module/image' |
Media Library picker |
| Link | type: object + $ref: 'json-schema-definitions://canvas.module/link' |
URL + link text input |
| Number | type: integer or type: number |
Numeric input |
| Boolean | type: boolean |
Toggle |
| Enum/select | type: string + enum: [value1, value2] |
Select dropdown |
Pattern
An SDC component for Canvas follows standard Drupal SDC conventions, organized in a single directory:
my_theme/
components/
hero/
hero.component.yml ← required: metadata, props, slots
hero.twig ← required: Twig template (NOT .html.twig)
hero.css ← optional: component styles
hero.js ← optional: component JS behaviors
Canvas automatically discovers ALL SDC components from all enabled modules and themes. There is no registration step.
*.component.yml schema:
# hero.component.yml
$schema: 'https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json'
name: Hero
status: stable
group: Marketing # Groups components in Canvas panel
description: 'Full-width hero with headline, subtext, CTA, and background image.'
props:
type: object
properties:
headline:
type: string
title: Headline
description: 'Main hero headline text.'
examples:
- 'Welcome to our platform'
image:
type: object
title: Background Image
$ref: 'json-schema-definitions://canvas.module/image'
cta_text:
type: string
title: 'Button Label'
cta_url:
type: object
title: 'Button URL'
$ref: 'json-schema-definitions://canvas.module/link'
body:
type: string
title: Description
contentMediaType: text/html
x-formatting-context: block
slots:
badge:
title: Badge
description: 'Optional badge component above the headline.'
Twig template:
{# hero.twig #}
{% set image_attrs = create_attribute() %}
<section class="hero">
{% if badge is not empty %}
<div class="hero__badge">{{ badge }}</div>
{% endif %}
<div class="hero__content">
{% if headline %}
<h1 class="hero__headline">{{ headline }}</h1>
{% endif %}
{% if body %}
<div class="hero__body">{{ body }}</div>
{% endif %}
{% if cta_text and cta_url %}
<a href="{{ cta_url.url }}" class="btn btn-primary">
{{ cta_text }}
</a>
{% endif %}
</div>
{% if image %}
{% include 'canvas:image' with {
image: image,
loading: 'eager',
fetchpriority: 'high',
} only %}
{% endif %}
</section>
Link prop structure: When a $ref: canvas.module/link prop is passed to Twig, it has .url and .title (link text) keys.
Slot rendering: Slots arrive as renderable Twig variables — render directly with {{ slot_name }}. No {% block %} needed.
Common Mistakes
- Wrong: Using
.html.twigextension → Right: Canvas (and SDC) only recognize.twig - Wrong:
<img src="{{ image }}">— image props are objects, not URLs → Right: Usecanvas:imagecomponent - Wrong: Adding
$reffor text strings that don't need the Media Library → Right: Use$refonly for image and link prop types - Wrong: Forgetting
x-formatting-contexton rich text props → Right: Without it, Canvas may not show the CKEditor widget - Wrong: Putting components in
templates/→ Right: SDC components must be incomponents/ - Wrong: Using
{% embed %}with{% block %}for Canvas:image → Right: Always use{% include ... only %}
See Also
- SDC Props Reference for all prop types in detail
- SDC Slots for slot behavior
- SDC Image Handling for image patterns
- Official SDC docs: https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components
- Canvas SDC docs: https://project.pages.drupalcode.org/canvas/sdc-components/