Problem/Motivation

Canvas Code Components (JsComponent component source) are currently not converted into structured Custom Elements output.

Canvas currently supports two Code Component types:

- `react` components render as opaque Astro island markup.
- `external` components are owned by a decoupled frontend and render as empty markup in Drupal.

Consequently, their component identity, resolved props, and nested slots are not represented in Custom Elements output.

Proposed resolution

Update `CanvasRenderConverter` to support both `type=react` and `type=external` Canvas Code Components.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

wotnak created an issue. See original summary.

wotnak’s picture

Status: Active » Needs review
fago’s picture

Amazing, thank you! Code looks good and is sound, also does well improve cache-metadata support.

The one point I'm a bit unsure is: What does a consumer actually want / need for code components?

Since they are all bundled and run-able standalone, I could see a decoupled frontend just wanting to make them work as is, i.e. load the preact bundle and run theme as astro-island. That keeps the canvas editing features working as intended.

But then, you might want to sync code components over and use the decoupled version of it, or a hand-written alternative.

So I think we have both use-cases, both seem valid. But how do we know, what is intended?

I think it would be nice to have some control over that. e.g. when a new component is added by an editor, I'd assume the safer default would be have it working out-of-the box, i.e. render an astro island. but then, the canvas-sync process or frontend person might want to change this to the coupled output.

Or maybe I'm overcomplicating this, and we shall simply serve the bundle-URL to the frontend, so it can decide? thoughts?

fago’s picture

oh, also a good point raised by an AI reivew. Does canvas escape this?

AstroIsland documents string slot values as plain text ("String values will be treated as plain text"). convertJsComponent() passes non-array slot content into setSlot(), which wraps bare strings in Markup::create() — i.e. unescaped raw HTML. A string slot with user-provided text would be escaped by canvas but emitted raw in CE output. Suggest Html::escape() for plain strings (keep MarkupInterface as-is) to match the island's semantics.