Overview
SDCs can have default images. See for example tests/modules/xb_test_sdc/components/image-optional-with-example.
We need equal functionality for code components (JavaScriptComponent config entities).
To achieve this, we'll need to bring in part of the PoC at https://git.drupalcode.org/project/experience_builder/-/commit/8ecc46f91... from >1 year ago.
Proposed resolution
- ✅ Make it possible to specify the filename of the default image just like is the case for the above SDC:
--- a/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml +++ b/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml @@ -12,7 +18,7 @@ props: type: object examples: - - src: 'https://placehold.co/1200x900@2x.png' + src: cosmo.jpg width: 1200 height: 900 - ✅ Make it possible for that filename to be tied to a
Fileentity by specifying a content dependency:--- a/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml +++ b/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml @@ -1,7 +1,13 @@ uuid: 3066d9d2-75f8-444d-a733-644698b43ad4 langcode: en status: true -dependencies: { } +dependencies: + content: + file:file:<UUID> machineName: xb_test_code_components_vanilla_image name: Vanilla Image block_override: null - ✅ The above is then the updated YAML representation of this config entity while stored in the Drupal DB.
- ✅ Add
DefaultRelativeUrlPropSourcesupport. Which requires updatingJsComponent::rewriteExampleUrl()to resolvecosmo.jpgto something like/sites/defaults/files/js_component/defaults/cosmo_1.jpg(assuming this is the second component pointing tocosmo.jpg: theFileentity's mechanisms will have detected that this file already existed, so it might resolve to a slightly different filename, but theexamplesentry in the definition will still work!). Otherwise the default image won't render in actual instances of this code component. - ✅ During export, ensure that the content dependency (
file:file:<UUID>) is carried along with the config entity, to allow it to be reconstructed (File::create(…)->save()) on another site, and have that code component work as if magic! That's where the PoC comes in.
--- a/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml +++ b/tests/modules/xb_test_code_components/config/install/experience_builder.js_component.xb_test_code_components_vanilla_image.yml @@ -1,7 +1,13 @@ uuid: 3066d9d2-75f8-444d-a733-644698b43ad4 langcode: en status: true -dependencies: { } +dependencies: + content: + file:file:<UUID> +# @see https://git.drupalcode.org/project/experience_builder/-/commit/8ecc46f9141b0e563605b33ebdae7baf1d7730fc +encoded_entities: + encoded_files: + …shrug… machineName: xb_test_code_components_vanilla_image name: Vanilla Image block_override: null
User interface changes
None, this is about back-end support only; not even including internal HTTP API support.
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | Screenshot 2026-02-04 at 3.31.40 PM.png | 679.41 KB | wim leers |
Issue fork canvas-3532574
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:
Issue fork experience_builder-3532574
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:
- 3532574-javascriptcomponent-config-entities
changes, plain diff MR !1206
Comments
Comment #2
wim leersI wrote this issue summary together with @f.mazeikis 🤓
Comment #4
larowlan.
Comment #6
larowlan@mstrelan pointed out we have the 8.4 polyfill in 11.2 but not in 11.1
Comment #7
f.mazeikis commentedPushed all the work so far, including working tests. @larowlan had some feedback, I think I've addressed most of it, but happy to get back to it if there's more.
Moving into ready for review.
Comment #8
wim leers#6: That should be fine, because XB bumped its requirement to 11.2 in #3492722: Update XB to require Drupal 11.2? That's what's in
0.5.0-alpha1, so <0.5 is for Drupal <11.2, >=0.5 is for Drupal >=11.2That was pretty fast! Reviewing… 🤓
Comment #9
lauriiiWe can work around this in beta by uploading images to media library and manually referencing them in component code. This is obviously not great and doesn't allow components to be moved from environment to another so we definitely still need this. Just trying to avoid rushing this before the beta.
Comment #10
mstrelan commentedRe polyfill:
Regardless of core version no reason XB couldn't add it as a dep, just give it a loose constraint so it doesn't conflict with core.
Comment #11
wim leersLooking promising!
\Drupal\Tests\experience_builder\Functional\XbConfigEntityHttpApiTest::testJavaScriptComponent()Comment #12
f.mazeikis commentedAddressed everything on MR and in #11.
Comment #13
larowlanGreat work @f.mazeikis - did another review and added some comments/observations
Comment #14
wim leers🏓 Responded to @f.mazeikis' most pressing question; didn't do a full review, but … the scope here is now no longer so narrow, but generic, thanks to #3524130: Define JSON Schema $refs for linking/embedding videos and linking documents + #3534601: Add a Video prop type to the Code Component editor; requires adding `file` as default `StaticPropSource`, `FileWidget` support and various infrastructure improvements.
Comment #15
f.mazeikis commentedI've addressed most of the feedback, replied with reasoning for the rest. This might not be complete, but a second pass review and further feedback on Comment on lines +802 to +804 would be beneficial.
Comment #16
f.mazeikis commentedComment #17
wim leersI'll review tomorrow — it's possible @larowlan will beat me to it, so not yet self-assigning.
Comment #18
wim leersThanks for the excellent docs additions 👏, that made it 10x easier to review this! 🥳
(Still in the process of reviewing.)
Created #3538711: [PP-1] Add support for example images for Code Components' image props for the actual feature that this is intended to unblock.
Comment #19
wim leersFinished reviewing the MR. Epic work! 🤩 Confirmed that it meets all 5 goals outlined in the issue summary! 👍
My commits/self-addressed:
Remaining feedback:
Fileentity in a test — what am I missing?encoded_filesitself; a config export+import could become an attack vector. See https://git.drupalcode.org/project/experience_builder/-/merge_requests/1... + https://git.drupalcode.org/project/experience_builder/-/merge_requests/1... + https://git.drupalcode.org/project/experience_builder/-/merge_requests/1...Thanks, @larowlan for creating #3537728: [PP-1] Consider adding ramsey/uuid for hash-based UUID (v5) generation for default files — linked to it 👍
Comment #20
wim leersAsked @larowlan to double-check my security concerns, and per https://git.drupalcode.org/project/experience_builder/-/merge_requests/1... seems like he's +1 😅
Comment #21
effulgentsia commentedComment #22
wim leersDiscussed with @f.mazeikis, @lauriii and @effulgentsia.
The bigger impact is actually for
ContentTemplates being fully exportable and importable (without the need for content syncing!), not code component default images.Comment #26
nagwani commentedComment #27
f.mazeikis commentedHad a call with @lauriii to clarify some things and here's the summary of the conversation:
There needs to be a simple way to export Content Template config, including all of its dependencies (config and images). Current plan is to have CLI commands for this, but eventually we will need UI for this as well. Export doesn't have to be a single .yml file, we just need the commands handling export/impor/upload/download to be easy and convenient to use.
Commands for exports and imports need to support two scenarios:
We need to decide if export/import and upload/download should be separate sets of commands. We also need to decide if we want to modify standard config export/import process to handle images (similar to how it was done in PoC) or if we want a separate command/flag to allow for "full config export with file/media dependencies".
When exporting a content template that uses Media Entity as an image, after importing on the destination site the expectation is this:
target_idincomponent_tree.inputs)target_idincomponent_tree.inputs)When we will pick up "Code Components" export functionality, same logic applies - "if CLI commands are easy to use for export/import/download/upload, then it's ok to have multiple fires per single Code Component export". According to @laurii, it should "just work". Whether it's a single file or multiple files in separate directories is implementation detail.
Comment #28
nagwani commentedComment #29
wim leersDiscussed this in detail with @f.mazeikis. We tried to figure out if there would be a reasonable way to rely as much as possible on 11.3's new content exporting functionality (already in use by Drupal's Recipes ecosystem!).
We think we see a way forward. It'd require:
👇
Exported
So, applied to a concrete Canvas code component for both the "pure Drupal core" scenario and a "Acquia Source/DAM" scenario, an exported code component would look like this:
NO dependenciesa single module dependency:acquia_dam+ a "well known" URI that specifies "Acquia DAM" as the providerImported
Upon importing the code component, these URIs would need to be: 1) validated (that they are accessible, resolve, etc.), 2) after passing validation, transformed to concrete, actual image/video/… URLs
WDYT, @lauriii?
Comment #30
wim leersForgot one thing: for Acquia Source/DAM, it would say: