Updating this issue to align with the broader proposal in #37275 (retire the standalone fundamentals/unions.md and integrate union content into existing articles in context). My earlier write-up proposed too much new content under a "## Blazor" header in a standalone article; this version keeps things small and distributes the few genuinely Blazor-specific behaviors into the existing Blazor articles.
Verified end-to-end against .NET 11 Preview 6 (11.0.100-preview.6.26315.102):
Where Blazor-specific union content should live
For everything that's "just STJ" (case selection, classifiers, [JsonUnion]), link out to the STJ docs — don't re-document it in Blazor.
| Topic |
Article |
Form |
| Component parameters can be union-typed |
blazor/components/index.md (Component parameters section) |
One short paragraph + a Slot(string, MarkupString, RenderFragment) example — the canonical Blazor union scenario |
| Razor literal-attribute workaround |
Same paragraph above, as a brief note |
One line: Content="hello" doesn't compile against a union-typed parameter; use Content="@("hello")". Tracked at dotnet/razor#13188. Remove once that ships. |
DynamicComponent boxing rule |
blazor/components/dynamiccomponent.md |
One short paragraph: dictionary values for union-typed parameters must be boxed as the union, not the raw case value, because the implicit conversion is compile-time only |
| Persisted component state / prerendering caveat |
blazor/components/prerender.md (or wherever PCS is documented) |
One sentence: user-configured JsonSerializerContext doesn't flow into the unions deserializer; use [JsonUnion(TypeClassifier = …)] per-type instead |
| JS interop |
blazor/js-interop/call-javascript-from-dotnet.md / call-dotnet-from-javascript.md |
No new content needed beyond a one-line "union types are supported" mention, linking to STJ |
EventCallback<TUnion>, CascadingValue<TUnion>, generic TItem inference, trimming/AOT in WASM, and Hot Reload all just work with no special guidance — leaving them undocumented is the right call. If anyone asks, the answer is "it's a normal generic type parameter / normal trimmed app / normal hot reload edit."
Net Blazor footprint: ~3 short additions to existing articles, each a paragraph or two. No standalone Blazor unions doc, no "## Unions" landing page in Blazor.
cc @guardrex
Updating this issue to align with the broader proposal in #37275 (retire the standalone
fundamentals/unions.mdand integrate union content into existing articles in context). My earlier write-up proposed too much new content under a "## Blazor" header in a standalone article; this version keeps things small and distributes the few genuinely Blazor-specific behaviors into the existing Blazor articles.Verified end-to-end against .NET 11 Preview 6 (
11.0.100-preview.6.26315.102):/unions-demo)Where Blazor-specific union content should live
For everything that's "just STJ" (case selection, classifiers,
[JsonUnion]), link out to the STJ docs — don't re-document it in Blazor.blazor/components/index.md(Component parameters section)Slot(string, MarkupString, RenderFragment)example — the canonical Blazor union scenarioContent="hello"doesn't compile against a union-typed parameter; useContent="@("hello")". Tracked at dotnet/razor#13188. Remove once that ships.DynamicComponentboxing ruleblazor/components/dynamiccomponent.mdblazor/components/prerender.md(or wherever PCS is documented)JsonSerializerContextdoesn't flow into the unions deserializer; use[JsonUnion(TypeClassifier = …)]per-type insteadblazor/js-interop/call-javascript-from-dotnet.md/call-dotnet-from-javascript.mdEventCallback<TUnion>,CascadingValue<TUnion>, genericTIteminference, trimming/AOT in WASM, and Hot Reload all just work with no special guidance — leaving them undocumented is the right call. If anyone asks, the answer is "it's a normal generic type parameter / normal trimmed app / normal hot reload edit."Net Blazor footprint: ~3 short additions to existing articles, each a paragraph or two. No standalone Blazor unions doc, no "## Unions" landing page in Blazor.
cc @guardrex