UI RENDERING & SSR FEATURE
Component Script Assets
No more “remember to include the JS somewhere on this page”. If a component needs optional client enhancement, the contract lives on the component itself.
Feature Guide
A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.
What this does
A Semitexa SSR component can declare its own optional enhancement asset, so the client behavior belongs to the component contract instead of being manually remembered by the page.
How it works
Add script to #[AsComponent], let ComponentRenderer auto-require the runtime and the declared asset when that component actually renders, and register the client behavior through SemitexaComponent.register() so the runtime can mount each rendered root.
Why it matters
This closes one of the oldest sources of frontend drift: the HTML lives in the component, but the behavior is hidden in page-level includes and boot glue. Semitexa keeps markup and optional enhancement under the same component ownership model.
Key concepts
- script
- Optional AsComponent field that declares the canonical enhancement asset key.
- auto-require
- The renderer pulls in the runtime and the component asset only when the component is present on the page.
- SemitexaComponent.register()
- Frontend runtime API that registers one mount function for a named SSR component.
- component root
- The rendered root element annotated so the runtime can mount behavior per instance.
Component Script Assets
The SSR component owns its optional enhancement asset.
These cards are plain SSR markup on first paint. Their behavior appears only because the component contract itself declares a script asset, and the runtime mounts that script per rendered root.
Shell
Server HTML first
The initial markup is already meaningful before any client enhancement runs.
Server rendered shell. Waiting for optional client enhancement…
Ownership
Behavior travels
The page did not manually remember this asset. The component contract did.
Server rendered shell. Waiting for optional client enhancement…
Scale
One asset, many roots
The same script loads once, then mounts each rendered component instance independently.
Server rendered shell. Waiting for optional client enhancement…
script:
Declared on #[AsComponent]
1x
Asset load per page
n
Root mounts per rendered instance
Verified against Semitexa Ultimate 2026.09.19.1020
Component Script Assets
No more "remember to include the JS somewhere on this page". If a component needs optional client enhancement, the contract lives on the component itself. A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.
How it works
The script key in #[AsComponent] declares the canonical asset that enhances this component. The component renderer auto-requires that script only when the component actually appears on the page. On the client side, SemitexaComponent.register() mounts the behavior per component root, so one script safely enhances many instances.
The rules
- The script is declared on the component contract, not remembered manually by the page.
- The asset loads only if that component actually rendered on the page.
- The runtime mounts behavior per component root, so one script can safely enhance many instances.
- The script remains optional enhancement, not a second rendering authority.
- The component keeps owning its surface: Twig for HTML, optional script for progressive enhancement.
Key mechanisms
script— canonical asset key declared directly in#[AsComponent].auto-require— ComponentRenderer requires the runtime and the asset only when the component appears.SemitexaComponent.register()— client behavior registers once and mounts each rendered component root independently.- No page glue — feature pages stop manually remembering which component enhancement script to include.
Why this matters
Page-level script includes create implicit dependencies between templates and JavaScript files. When a component moves to a different page, the include has to move too. Declaring the script on the component class makes the dependency explicit and co-located, so the component can render anywhere without extra wiring.
How it works
Add script to #[AsComponent], let ComponentRenderer auto-require the runtime and the declared asset when that component actually renders, and register the client behavior through SemitexaComponent.register() so the runtime can mount each rendered root.
Why it matters
This closes one of the oldest sources of frontend drift: the HTML lives in the component, but the behavior is hidden in page-level includes and boot glue. Semitexa keeps markup and optional enhancement under the same component ownership model.
Key concepts
- script
- Optional AsComponent field that declares the canonical enhancement asset key.
- auto-require
- The renderer pulls in the runtime and the component asset only when the component is present on the page.
- SemitexaComponent.register()
- Frontend runtime API that registers one mount function for a named SSR component.
- component root
- The rendered root element annotated so the runtime can mount behavior per instance.