Problem
Client-rendered sites routinely carry a large share of their content behind interaction: click a zone on a map, a spec panel fills; type in a search box, a card grid filters. The conversion pipeline currently captures the page in its initial state only, so that content never reaches WordPress. The imported page keeps the affordance — the clickable-looking artwork, the search input, the filter chips — but none of the behaviour and none of the hidden content.
The result is worse than an omission: the imported site presents dead UI that makes a promise it cannot keep.
Worked example
cerberusmed.base44.app/facility (base44/React) renders an interactive facility map: 19 clickable SVG zones driving a sibling detail panel.
Live site, measured with Playwright:
clickable zones (svg g.cursor-pointer): 19
click zone FR1 -> panel text grows by 580 characters:
"Flower Room 1 / Production / Operational / ZONE DESCRIPTION A fully climate-controlled
1,530 sq ft flower room running an 18/6 then 12/12 light cycle ...
TECHNICAL SPECIFICATIONS LIGHT CYCLE 18/6 -> 12/12 CO2 SETPOINT 1,200-1,500 ppm
TEMP. RANGE 23-25 C HUMIDITY 45-55 % RH ..."
Imported WordPress page:
clickable zones: 0
map is a materialized <img> asset
panel text (permanent): "INTERACTIVE FLOOR PLAN — Select any zone on the map to view
technical specifications and operational details."
click the map -> body text length 1523 before, 1523 after (no change)
Scale of the loss
Extracted from the source bundle resources/assets/index-BHKgk633.js:
- 16 named zones (Flower Room 1-9, Mother / Clone / Veg / Dry / Trim Room, Fertigation, Utility, Packaging, Shipping & Receiving); 19 clickable targets
- 39 long descriptions, ~10,170 characters total
- per-zone structured specs: light cycle, CO2 setpoint, temperature range, humidity, canopy, status
The entire visible facility page is 1,523 characters. The interaction-gated content is roughly 7x the whole visible page, and none of it is imported.
The same site's /strains page has a second instance: a search input and 12 filter chips that all render but filter nothing.
This is not an SVG-materialization artifact
The behaviour was never captured in either materialization path. Before the SVG took the native image path, it was a core/html block whose 19 <g class="cursor-pointer"> elements were present in the DOM — and clicking still did nothing (body text 1710 chars before and after). React handlers do not serialize into static HTML. Materializing the SVG as an editable core/image neither caused nor worsened this.
The capability partly exists
Data Liberation Agent already captures interaction states. On this same site it captured a Radix disclosure on /gmp:
{ "schema": "data-liberation/interaction-states/v2",
"states": [ { "status": "captured", "kind": "disclosure",
"trigger": { "tag": "button", "label": "Full Batch Traceability",
"ariaControls": "radix-:r1:" },
"dialog": { "role": "region", ... } } ] }
So the primitive is real; its recognition vocabulary is the gap. The facility map is neither a disclosure nor a dialog: it is N sibling click targets driving a shared detail region, where the region's content varies per target. Nothing in the current kind vocabulary describes that shape.
Why this matters generally
"N selectable items drive one detail region" is not exotic — it is the dominant idiom for product pickers, pricing toggles, tabbed specs, filterable catalogues, store locators and interactive maps, and it is emitted by default by base44, Lovable, v0 and similar generators. Any source of that shape currently imports as a brochure of an application.
Suggested shape (for discussion, not a decided design)
Three separable pieces:
- Capture (DLA): extend interaction-state recognition beyond disclosure/dialog to "selectable set drives a shared region" — enumerate the click targets, drive each, and record the resulting region content as states. The existing
interaction-states/v2 envelope looks like it can carry this.
- Represent (blocks-engine): a block that holds N states plus a selector. The Gutenberg Interactivity API is the natural target so this stays native and editable rather than a preserved runtime island.
- Honesty gate (static-site-importer): when a source region is interaction-gated and its states were not captured, that should be a reported diagnostic rather than silently shipping dead UI with an instruction the page cannot honour. Today this import reports
content_loss_count: 0 and quality_pass: true while ~10k characters of content and all 19 interactions are missing — the quality counters model absence of fallback blocks, not absence of behaviour.
Item 3 is worth considering on its own even before 1 and 2: a truthful diagnostic is cheap and prevents "quality_pass: true" from overstating the result.
Reproduction
# Studio PR 3952, DLA 6e8131f4, SSI 06dfc6b5, blocks-engine 99d41ce5d
studio site create --path <dir> --from https://cerberusmed.base44.app/ \
--static-site-importer-path <ssi-dev-package.zip>
# then compare the live /facility against the imported /facility
AI assistance disclosure: investigated and written with Claude Sonnet 4.5 via opencode. The agent ran the imports, drove the live and imported pages with Playwright to measure interaction state, extracted the zone inventory from the source bundle, and drafted this issue. All measurements quoted above were produced by those runs and are reproducible with the commands shown.
Problem
Client-rendered sites routinely carry a large share of their content behind interaction: click a zone on a map, a spec panel fills; type in a search box, a card grid filters. The conversion pipeline currently captures the page in its initial state only, so that content never reaches WordPress. The imported page keeps the affordance — the clickable-looking artwork, the search input, the filter chips — but none of the behaviour and none of the hidden content.
The result is worse than an omission: the imported site presents dead UI that makes a promise it cannot keep.
Worked example
cerberusmed.base44.app/facility(base44/React) renders an interactive facility map: 19 clickable SVG zones driving a sibling detail panel.Live site, measured with Playwright:
Imported WordPress page:
Scale of the loss
Extracted from the source bundle
resources/assets/index-BHKgk633.js:The entire visible facility page is 1,523 characters. The interaction-gated content is roughly 7x the whole visible page, and none of it is imported.
The same site's
/strainspage has a second instance: a search input and 12 filter chips that all render but filter nothing.This is not an SVG-materialization artifact
The behaviour was never captured in either materialization path. Before the SVG took the native image path, it was a
core/htmlblock whose 19<g class="cursor-pointer">elements were present in the DOM — and clicking still did nothing (body text 1710 chars before and after). React handlers do not serialize into static HTML. Materializing the SVG as an editablecore/imageneither caused nor worsened this.The capability partly exists
Data Liberation Agent already captures interaction states. On this same site it captured a Radix disclosure on
/gmp:{ "schema": "data-liberation/interaction-states/v2", "states": [ { "status": "captured", "kind": "disclosure", "trigger": { "tag": "button", "label": "Full Batch Traceability", "ariaControls": "radix-:r1:" }, "dialog": { "role": "region", ... } } ] }So the primitive is real; its recognition vocabulary is the gap. The facility map is neither a disclosure nor a dialog: it is N sibling click targets driving a shared detail region, where the region's content varies per target. Nothing in the current
kindvocabulary describes that shape.Why this matters generally
"N selectable items drive one detail region" is not exotic — it is the dominant idiom for product pickers, pricing toggles, tabbed specs, filterable catalogues, store locators and interactive maps, and it is emitted by default by base44, Lovable, v0 and similar generators. Any source of that shape currently imports as a brochure of an application.
Suggested shape (for discussion, not a decided design)
Three separable pieces:
interaction-states/v2envelope looks like it can carry this.content_loss_count: 0andquality_pass: truewhile ~10k characters of content and all 19 interactions are missing — the quality counters model absence of fallback blocks, not absence of behaviour.Item 3 is worth considering on its own even before 1 and 2: a truthful diagnostic is cheap and prevents "quality_pass: true" from overstating the result.
Reproduction
AI assistance disclosure: investigated and written with Claude Sonnet 4.5 via opencode. The agent ran the imports, drove the live and imported pages with Playwright to measure interaction state, extracted the zone inventory from the source bundle, and drafted this issue. All measurements quoted above were produced by those runs and are reproducible with the commands shown.