{
  "id": 4804292,
  "title": "A Green Build Is Not a Route Test",
  "url": "https://urgent.news/2026/09/01/a-green-build-is-not-a-route-test",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-01T06:21:34.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/iqtechsolutions/a-green-build-is-not-a-route-test-4oec"
  },
  "original_language": "en",
  "account": "A Blazor Hybrid application can compile flawlessly yet crash upon startup due to route conflicts. These conflicts arise not from individual components but from their collective composition. When multiple assemblies share the same route, the issue only manifests when the router initiates during runtime. This highlights the need for route ownership to be an architectural contract rather than a mere @page directive.\n\nShared UI libraries often host common pages, allowing each application host to retain its unique authentication, platform services, and startup behaviors while reusing page code. However, this shared approach can introduce route collisions when different hosts independently declare the same path in the shared assembly. The compiler does not flag these duplicate routes, as it only examines each component individually. It is only when the application composition occurs that the conflict becomes apparent.\n\nThe issue is not unique to Blazor; it is a general modularity problem. A module may be structurally valid in isolation, yet the overall application graph can become invalid upon composition. This leads to problems such as dependency-injection cycles, duplicate HTTP endpoints, conflicting configuration keys, and route collisions. For Blazor, the timing of the failure is particularly inconvenient, as the collision may not be detected until the router initializes during the first load.\n\nThe decision to use a MAUI (Multi-platform App UI) host introduces additional complexity. While a MAUI build can create native binaries for different platforms, it does not guarantee that a BlazorWebView can successfully start, compose its scanned assemblies, and navigate. Real-device or emulator startup tests can validate these aspects, but they require significant resources, including installation, boot time, device management, and added CI instability.\n\nTo address this, a focused collision guard can be implemented. This guard does not need to replicate the entire Razor runtime but should answer a critical architectural question: are any routes declared more than once within the assemblies scanned by each host? The guard can enumerate the .razor source files for a host and its shared UI project, ignoring generated bin and obj trees, recognizing only complete @page directive lines, normalizing paths with a consistent case policy, and grouping the declarations by route. The guard should then run the same assertion for every head.\n\nA practical implementation of this guard involves enumerating the .razor files, removing comments and generated code, and grouping the routes for comparison. If a collision is detected, the guard should report the generalized host and the source locations of the conflicting routes, enabling quick resolution of ownership issues.\n\nIt is important to note that this source-level guard has limitations. It may pass silently if the parser fails to find any routes, resulting in a false sense of security. Therefore, an anti-vacuous test should be added to ensure that the parser detects a minimum number of routes. Additionally, comments containing route examples should be ignored, as they can create false positives when counted as declarations. The guard should also exclude generated copies to avoid false positives caused by parser bugs.\n\nWhile a source-level guard is fast and portable, it is tied to project layout and Razor syntax, and it does not exercise the actual router, dependency injection, native lifecycle, or device packaging. Conversely, a device startup test provides higher-fidelity evidence of the application's ability to start and navigate in its platform environment. However, this test is slower and more operationally expensive.\n\nIn summary, a combined approach is recommended: utilize the source-level guard for immediate feedback on route uniqueness across each host, and incorporate at least one device-startup test when the release risk justifies the additional cost. This approach ensures that developers have both structural and runtime validation of their application's route composition, minimizing the risk of runtime failures due to route collisions.",
  "summary": "A Blazor Hybrid application can compile successfully and still fail as soon as its router starts. The uncomfortable part is that nothing needs to be wrong with the individual components. The failure can live in the composition of otherwise valid Razor pages: two scanned assemblies declare the same route, and the conflict is only discovered at runtime. That makes route ownership an architectural…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}