Change record status: 
Project: 
Introduced in branch: 
1.x
Introduced in version: 
1.8.0
Description: 

Summary

Validation and translatability of a component instance's inputs are now computed from the component version the instance references, never from the live implementation's JSON schema.

Before

Config-defined component trees (page regions, patterns, content templates, field default values) validated every instance's inputs against the component's live JSON schema. Removing an optional prop from an SDC or code component — which creates a new component version — made previously valid, unchanged trees that still reference the old version invalid: '<prop>' is not a supported key. Which strings translation systems (config translation, TMGMT) offered for translation could likewise silently change when the live component changed.

After

Each prop in each version of a Component config entity stores a required derived_schema_metadata key in its prop_field_definitions, retaining the translation-relevant part of the prop's JSON schema shape:

prop_field_definitions:
  # A plain single-line string (`type: string`): translatable, no extra
  # constraints matter, so the retained shape is empty.
  title:
    field_type: string
    expression: 'ℹ︎string␟value'
    derived_schema_metadata:
      string_shape: {}
  # A multi-line string (`type: string, pattern: (.|\r?\n)*`).
  code:
    field_type: string_long
    expression: 'ℹ︎string_long␟value'
    derived_schema_metadata:
      string_shape:
        pattern: '(.|\r?\n)*'
  # Rich text (`type: string, contentMediaType: text/html`); the
  # `x-formatting-context` (block/inline) is not retained — it does not
  # affect translatability.
  body:
    field_type: text_long
    expression: 'ℹ︎text_long␟processed'
    derived_schema_metadata:
      string_shape:
        contentMediaType: text/html
  # A URI-esque string (`format: uri`, `uri-reference`, `iri` or
  # `iri-reference`).
  link:
    field_type: link
    expression: 'ℹ︎link␟url'
    derived_schema_metadata:
      string_shape:
        format: uri-reference
  # A prop that holds no translatable text — e.g. an enum, an email,
  # integer, or any non-string shape: empty mapping, no `string_shape`.
  variant:
    field_type: list_string
    expression: 'ℹ︎list_string␟value'
    derived_schema_metadata: {}

string_shape keeps only the keys that matter to translation systems: pattern (multi-line), contentMediaType (rich text) and format (URI-esque). type: string is implied and omitted, so a plain single-line string retains an empty string_shape. Cardinality is irrelevant: an array of translatable items (e.g. type: array of strings) retains the item shape. Translatability is derived from this stored shape plus the prop's expression — a reference-backed prop holds structured data, not author-entered text, so it is not translatable even when its shape is string-like. Nothing is stored as a boolean, so translatability can be re-derived if the rules evolve.

Update path

canvas_post_update_0021 (plus a presave heal) backfills the new key on all existing Component config entities. The key is excluded from the component version hash, so no new component versions are created and no version ids change.

⚠️ Component instances referencing older versions are not translatable

What shape a prop had when a past version was created is unknowable, so props of past versions are backfilled as not translatable. Only component instances referencing the active version of a component offer translation of their inputs. Automatic component instance updating moves instances to the active version over time, at which point their inputs become translatable. No content or configuration is lost; existing translations keep rendering.

For developers extending Canvas

All of the above applies only to component sources extending JsonSchemaPropsComponentSourceBase (SDCs and code components) — derived_schema_metadata lives in their prop_field_definitions (config schema type: canvas.json_schema_props), which is what makes their versioned inputs schema derivable at all. Block components are unaffected: their inputs are validated and translated against the block plugin's own block.settings.* config schema, whose keys already declare translatability natively (e.g. type: label), independently of component versions — this change neither adds nor removes translation support for block inputs.

A new extension point, ComponentSourceBase::settingsAffectingVersionHash(), lets any component source exclude purely derived settings from version-hash computation; the default implementation keeps all settings, and JsonSchemaPropsComponentSourceBase overrides it to strip derived_schema_metadata. PropShape::getTranslatableStringShape() is the single source of truth for which string shapes hold translatable text.

Impacts: 
Site builders, administrators, editors
Module developers
Themers
Site templates, recipes and distribution developers