Problem/Motivation
modules/contrib/experience_builder/ui/src/mocks/handlers.ts contains:
import { delay, http, HttpResponse } from "msw";
import components from "./fixtures/components.json"
import layoutDefault from "./fixtures/layout-default.json"
import mockPreviewDocument from "./preview";
const DEFAULT_DELAY = 200;
const handlers = [
http.get('/api/components', async () => {
await delay(DEFAULT_DELAY);
return HttpResponse.json(components)
}),
http.get('/api/layout/:id', async () => {
await delay(DEFAULT_DELAY);
return HttpResponse.json(layoutDefault)
}),
http.post<{}, { layout: any; model: any }>('/api/preview', async ({ request }) => {
await delay(DEFAULT_DELAY);
const {layout, model} = await request.json()
return HttpResponse.json({html: mockPreviewDocument(layout, model)});
}),
];
export default handlers;
This exists since #3450302: Consider swapping miragejs for msw (and https://git.drupalcode.org/project/experience_builder/-/commit/dacd3b69f... etc before it).
In order for these to stop using hardcoded markup in those JS fixtures, we need to actually implement these routes on the server side.
Steps to reproduce
Proposed resolution
It doesn't matter that these routes/URLs will change. What matters is that the client is starting to actually talk to the server.
So, implement:
/api/layout/:id. Hardcoding to only/api/layout/1is fine for now. The default layout should be empty./api/preview. This should match the markup that the mock logic atcreateHtmlFromLayoutData()currently generates.
It doesn't matter if this is hacky code or non-final mark-up. It will change anyway.
(Tricky: /api/components and /api/component/… are automatically remapped to /xb-components and /xb-component/… in ui/src/services/components.ts — cleaning that up is out of scope here.)
Remaining tasks
User interface changes
The UI starts being powered by the server side.

API changes
N/A
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | UI-bug-placing-component-no-model.gif | 5.09 MB | wim leers |
| #3 | connect-ui-to-drupal.gif | 2.55 MB | wim leers |
Issue fork experience_builder-3455898
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 #3
wim leersIt's alive! 🧟♀️
No slot support yet — for that we need #3455728: FieldType: Support storing component *trees* instead of *lists* first.
Hacky-as-hell, but good enough for now, to unblock next steps on the UI side. The labels assigned to components in the UI/config entities introduced in #3444417: "Developer-created components": mark which SDCs should be exposed in XB do show up.
Comment #4
wim leersFound one UI bug: dragging in a new "my CTA" component does result in a response from
/xb-render-component/…that contains the defaultpropsthat were used to render it (as well asmarkupto render it).But the request the UI makes to the
/api/previewroute does not include those default props for that newly placed component undermodel.(Alternatively: no request should be made to
/api/previewat all until the props are customized from the default initial value, which already is present undermarkupin the response from/xb-render-component/….)Comment #5
wim leersI gather that @jessebaker is fixing #4 here. So no more need for a follow-up.
As soon as that's ready, @jessebaker, PLEASE merge this 🙏
Comment #8
jessebaker commented