Roadmap: First-class Web Components support for Razor components (or endorse JS Render API + helpers)
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
We embed **Razor components** inside existing **Vue/React/Angular apps** (design-system widgets and micro-frontends). We see two paths:
**JS Render API** — RegisterForJavaScript(...) + Blazor.rootComponents.add(...) + dispose().
This is reliable, but every consumer must write glue (mount/update/dispose orchestration, event bridging, date/number normalization). Contracts vary team by team.
**Blazor Custom Elements** — attractive declarative contract, but currently experimental/unsupported and has gaps (e.g., no child content/templated components, unclear update semantics/events). This makes it risky as an enterprise boundary.
Result: teams either accept the risk of experimental CE or keep building bespoke wrappers on top of the JS API, leading to fragmentation and duplicated effort.
### Describe the solution you'd like
**Request A (preferred):** A clear roadmap to **graduate Blazor Custom Elements** from experimental to supported, with:
Support for **child content / templated components** (slot/RenderFragment mapping).
Documented **parameter update** semantics (properties vs attributes; rich object props update without re-add).
A standard **eventing model** (DOM CustomEvent with typed detail, bubbles+composed across Shadow DOM).
Explicit **lifecycle guarantees** (when instances are mounted/unmounted; disposal and cleanup).
Guidance for **RCL** assets (/_content/...) and script choice (blazor.webassembly.js / blazor.server.js vs blazor.web.js) for SPA embedding.
**Request B (if CE won’t be prioritized):** Explicitly endorse the JS Render API as the long-term contract and ship small official helpers to reduce glue:
**1. SPA Bridge SDK (JS/TS):**
```
await waitForBlazor();
const inst = await mount(el, "componentId", params); // Date→ISO handled
await update(inst || el, params); // live UpdateParams when available; else safe re-add
dispose(inst);
on(el, "my:event", (payload) => { ... }); // DOM CustomEvent conventions
```
- Normalizes Dates/numbers; attaches hostId; enforces bubbles+composed events; guards against concurrent mounts.
**2. Types & codegen:**
TypeScript typings for component parameters and event payloads (source from component metadata) to give strong types in host apps.
**3. Optional wrappers:**
Thin custom-element facade generator that uses the JS API under the hood (declarative for consumers, stable internals).
Tiny framework shims: Vue component, React wrapper, Angular directive — all built on the same bridge SDK.
**4. Docs & guidance:**
Update docs to present one endorsed path (JS API + helpers) with examples for micro-frontends and design systems, and clarify blazor.web.js readiness criteria.
**Acceptance criteria (either path):**
- A supported way to embed Razor components cross-framework with stable lifecycle, typed params, and rich events—without each team writing bespoke glue.
- Clear statement on long-term support (CE vs JS API) and capabilities scope.
### Additional context
**- Why now**: Many orgs are standardizing on Web Components for cross-framework reuse. Angular already binds CE props/events; React 19 improved CE interop; Vue plays nicely with DOM events. Razor components can participate—if Blazor provides a supported CE story or endorses the JS API with helpers.
**- Minimal repro / helper prototype (attached, see lower):**
A runnable sample demonstrating both patterns:
- JS Render API: mount a Razor component with a rich params object (date/bool/number/nested) and receive a rich payload back via CustomEvent.
- Custom Element facade: a thin wrapper that calls rootComponents.add(...) internally, exposing a clean declarative tag while retaining explicit dispose() control.
**Impact if unaddressed**: Teams continue to ship ad-hoc wrappers; inconsistent contracts; pressure to adopt experimental CE; slower adoption of Razor components in heterogeneous SPA estates.
**- What feedback would help you most:**
- Whether CE is intended to graduate (and rough timeframe).
- If not, confirmation that the JS Render API + official helpers is the long-term direction, so we can align internal standards and avoid bespoke solutions.
Please see: https://github.com/paulvanbladel/BlazorWebComponentsInteropDemo
Contributor guide
Assessment
This issue has not been assessed yet.