"Razor tag resolution ignores global usings"
▸ SYMPTOM
A component from an external or library namespace renders as a blank/inert box in the UI. The build is GREEN and the same type resolves correctly inside @code { } blocks. No compile error — the tag just silently does nothing.
▸ CAUSE
The Razor compiler does not consult global using directives when resolving markup tags. When a namespace is imported only via a global using in Assembly.cs, the Razor tag for a component in that namespace triggers RZ10012 ("Found markup element with unexpected name ... it may be a component") as a warning, not an error. The tag silently falls back to rendering as a plain HTML element.
The C# code context (@code { }) does see global usings, so the class resolves fine in code-behind while its markup tag does not — a confusing split where the type exists in code but is dead in markup.
A warnings-tolerant dotnet build stays green, so the UI is broken while compilation "succeeds".
▸ FIX
Add an explicit @using <Namespace> line at the top of every .razor file that renders components from external or library namespaces as tags:
@using MyLibrary.Components
@using Sandbox
@using Sandbox.UIThe habit of including @using Sandbox / @using Sandbox.UI in panel skeletons generalizes to any consumed library namespace.
Detection: treat RZ10012 as an error in review — do not let it sit as a tolerated warning. Grep .razor files for library component tags that lack a matching @using.
▸ WHY IT WORKS
Razor's tag lookup walks the file-local @using directives (and _Imports.razor if present), not the project-wide global usings. The global using feature is a C# compiler concept that the Razor tag-resolution pass simply does not participate in. An explicit @using puts the namespace into Razor's own resolution scope, making the tag bind to the real component type instead of falling through to plain HTML.
- Published