Overview
To enable simple use cases in dynamic code components, we need to expose specific pieces of data to the code components via drupalSettings. This includes information that is usually rendered by blocks like system branding or breadcrumbs, but will now be needed directly in dynamic code components — which will deprecate code overrides (#3505993: Code Components as Block Overrides, step 1).
Proposed resolution
Populate the following data in drupalSettings under a new top-level key xbData (note: not under xb, which is reserved for internal Experience Builder needs):
{
xbData: {
baseUrl: 'https://www.example.com',
branding: {
homeUrl: '/',
logo: '/core/misc/logo/drupal-logo.svg',
siteName: 'My awesome website',
siteSlogan:
"<p>This website is the best. It's better than all the rest.</p>",
},
breadcrumbs: [
{
key: 'front_page',
text: 'Home',
url: '/',
},
{
key: 'news',
text: 'News',
url: '/news',
},
{
key: 'business',
text: 'Business',
url: '/business',
},
],
pageTitle: 'Home',
},
}
The data needs to be added everywhere where the astro_island render element (\Drupal\experience_builder\Element\AstroIsland) is rendered, so not only on the XB UI.
The proposed shape follows what we previously introduced in #3505993: Code Components as Block Overrides, step 1 — see /experimental/js-components-as-block-overrides/example-data/.
These settings will need to be attached in 2 places:
- For the actual live site and the preview inside the XB UI: Since this is intended to provide information for >=1
ComponentSources (currently only thejsone), this belongs in\Drupal\experience_builder\Hook\ComponentSourceHooks::pageAttachments(). - For the previews of components in the component list ("component hover"): update
\Drupal\experience_builder\Entity\Component::normalizeForClientSide()
Issue fork experience_builder-3531249
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
Comment #2
balintbrewsI added more details and what I propose as the data shape.
Comment #3
wim leersNote: spend zero seconds on making
pageTitlework, until #3502371: Make "Page title block" work A) also outside regions, B) on the only routes XB currently supports: content entity routes is in. Hardcode some string for now.Comment #4
wim leersAdded some implementation guidance.
Comment #5
balintbrews#3:
We need the page title inOr maybe what you're saying is that we need #3502371: Make "Page title block" work A) also outside regions, B) on the only routes XB currently supports: content entity routes even to be able to populate it indrupalSettings.xbDataregardless of that. #3502371: Make "Page title block" work A) also outside regions, B) on the only routes XB currently supports: content entity routes will enable the page title block to work, but we would like to support building a dynamic code component where users can access the raw page title and add custom markup around it. It was amongst our original goals for #3505993: Code Components as Block Overrides, step 1, but we dropped it due to the challenges with page title block.drupalSettings.xbDatahere? 🙂Edit: Yes, after re-reading your comment, that's what you were saying, sorry! 🙈
Comment #7
isholgueras commentedI think it's ready for the first review round
Comment #8
wim leersNice work here!
I'm missing three key things:
JavaScriptComponentconfig entities should at minimum declare that they depend ondrupalSettingsJavaScriptComponentconfig entities should ideally declare that they depend on specific data indrupalSettings— especially breadcrumbs data, because it massively worsens cacheabilityI'm fine with a
@todo+ stable-blocking follow-up issue to address the dependency information, but shipping a 1.0 like this is a no-go.Comment #9
isholgueras commentedComment #10
isholgueras commentedThere is only one thing left to do. How are the code component going to require that it depends on... breadcrumbs for example?
I still missing how, if I'm creating a code component, I'm going to depend on breadcrumb or pageTitle.
I mean, in the whole process as a user or XB user, I click in Add new, I get the editor and... where I define what features I will require?
I was playing around with a new schema Choice property,
drupalSettings, similar to ablockOverrideand list there all the options allowing developers to add it to the yaml files, maybe in the future adding them to the UI, but that's very much out of scope here.Any thoughts here?
Comment #11
wim leersComment #12
wim leerspreg_match('/drupalSettings\.xbData/', $component->getJs(). I agree with the pragmatism until such a time we can use explicitimportstatements.\Drupal\experience_builder\Hook\ComponentSourceHooks::jsSettingsAlter()is not being called.So instead of:
it should become
drupalSettings?.xbData?.v0?.branding?.homeUrl… which will allow for evolvability, backwards compatibility layers, deprecation warnings etc.
::getJs(), which is the saved JS, not the auto-save JS. This needs to reflect either. In fact, it probably makes sense to ALWAYS load alldrupalSettings.xbDatafor draft components, just to avoid race conditions: if I'd adddrupalSettingswhile editing the code in the code editor, they wouldn't be populated yet? See #3529677: `JavaScriptComponent`'s CSS library (prod/draft) should depend on global `AssetLibrary`'s asset library (prod/draft) for inspiration.Comment #13
wim leersOh, a crucial bit I forgot:
— I
— Claude
This is why in the commit I pushed, I used
hook_js_settings_alter(). XB doesn't create any new problem/challenge then, but just piggybacks on what Drupal core does 👍Comment #14
wim leersPaired with @isholgueras to get #12.2 working. Got it working, but not in the way I liked. So I dug deeper. Turns out we're running into a core bug: #3533354: `AssetResolver::getJsSettingsAssets()` calls `::getLibrariesToLoad()` with wrong asset type. Worked around it in https://git.drupalcode.org/project/experience_builder/-/merge_requests/1... 👍
Over to @isholgueras to address the remaining feedback — we're on the same page 🥳
Comment #15
wim leersMuch better! 🤩
Comment #16
wim leersComment #18
isholgueras commentedAfter chatting with @balintbrews, the resolution for this issue is not correct.
drupalSettings.xbDatashould be in global scope and appear only once. This branch does too much and it has some errors:- The preview (top right) doesn't work. When users create code, the client is not yet talking to the backend.
- The non-compiled code wont work.
The front-end API will consume this settings with methods (not decided yet) like
getPageData()(for title and breadcrumb) andgetSiteData()(for base URL and branding).Comment #19
effulgentsia commentedFrom chatting with @balintbrews, as I understand it there's only two problems with what got merged here:
Assuming it's only those two problems, let's handle them there, and I'm moving this one back to Fixed.
Comment #20
wim leersFYI: #3533535: Attach `xbData.*` asset library when loading XB UI, for use by the code component editor is green, #3533458: Change CodeComponentDataProvider::getRequiredXbDataLibraries() to base its logic on information provided by the front-end rather than on naive string/regex matching is blocked on FE.