Some economy and other notes
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
---
|
||||
sessionId: session-260930-201705-1ilk
|
||||
---
|
||||
|
||||
# Requirements
|
||||
|
||||
### Overview & Goals
|
||||
The objective is to ensure that deep link URLs (such as `https://zs.gameslopreference.ca/galaxy`, `/planetary-mastery-items`, `/StarSystem/...`, and `/SystemMastery/...`) load properly when requested directly or refreshed in production browsers, rather than resulting in 404 Not Found errors.
|
||||
|
||||
Providing robust URL resolution maximizes utility for end users by enabling direct bookmarking, shareable links, and reliable browser refreshes across deployment targets including Azure Static Web Apps and static hosting environments.
|
||||
|
||||
### Scope
|
||||
- **In Scope:**
|
||||
- Configuring Azure Static Web Apps navigation fallback rules (`staticwebapp.config.json`) in `ZeroSpace.Web/wwwroot`.
|
||||
- Adding universal static host SPA 404 redirect fallback (`404.html`) and client-side URL restoration in `ZeroSpace.Web/wwwroot/index.html`.
|
||||
- Ensuring static assets (images, CSS, JS, WASM binaries) remain directly accessible and properly cached without being captured by fallback rewrites.
|
||||
- Verifying publish and deployment compatibility with `ZeroSpace.Deploy`.
|
||||
|
||||
- **Out of Scope:**
|
||||
- Modifying backend APIs or database schemas in `ZeroSpace.ApiService`.
|
||||
- Altering Blazor internal routing logic in `App.razor` or `ReleaseGuard.razor`.
|
||||
|
||||
### User Stories
|
||||
- As a user navigating directly to `https://zs.gameslopreference.ca/galaxy`, I want the galaxy map page to render directly without encountering a host 404 error.
|
||||
- As a user sharing or bookmarking a deep link to a star system or planetary mastery item, I want the recipient to immediately load the exact target route.
|
||||
- As an administrator refreshing a deep page URL, I want the session and route to remain intact with zero broken navigation flows.
|
||||
|
||||
### Functional Requirements
|
||||
- Direct GET requests to client-side routes (e.g., `/galaxy`, `/planetary-mastery-items`) must return the main application shell (`index.html`) with HTTP 200/redirect so the Blazor WebAssembly client router can take over.
|
||||
- Requests for physical static files under `/images/`, `/css/`, `/js/`, `/lib/`, and `/_framework/` must continue to be served directly as static files or return standard 404s if missing, avoiding infinite loop rewrites.
|
||||
- URL query parameters and hash fragments must be preserved when client-side redirects occur.
|
||||
|
||||
### Non-Functional Requirements
|
||||
- **Performance & Reliability:** The redirect mechanism must execute with negligible overhead (<5ms execution time) before WebAssembly startup.
|
||||
- **Portability:** The solution must function seamlessly whether deployed via Azure Static Web Apps (`swa deploy`), containerized Nginx (`ZeroSpace.Web/nginx.conf`), or static CDN hosts.
|
||||
|
||||
# Technical Design
|
||||
|
||||
### Current Implementation
|
||||
- `ZeroSpace.Web` is a client-side Blazor WebAssembly application (`Microsoft.NET.Sdk.BlazorWebAssembly`) targeting .NET 10.
|
||||
- `ZeroSpace.Deploy` publishes the Web project to a temporary directory and deploys `wwwroot` to Azure Static Web Apps using `swa deploy`.
|
||||
- While `ZeroSpace.Web/nginx.conf` contains `try_files $uri $uri/ /index.html;` for Docker deployments, Azure Static Web Apps lacks a `staticwebapp.config.json` configuration, causing direct HTTP requests to deep paths like `/galaxy` to return 404 responses from Azure's edge servers.
|
||||
- `ZeroSpace.Web/wwwroot/index.html` currently lacks client-side deep URL reconstruction script handlers for static host fallbacks.
|
||||
|
||||
### Key Decisions
|
||||
- **Dual-Layer Fallback Strategy (Azure SWA + Universal SPA Redirect):**
|
||||
- *Decision:* Provide both `staticwebapp.config.json` for native Azure Static Web Apps server-side rewrites and `404.html` + `index.html` URL restoration script for generic static hosting.
|
||||
- *Rationale:* Maximizes availability and utility across all deployment topologies while delivering instant, clean URL serving on Azure SWA without redirect hops.
|
||||
|
||||
- **Explicit Asset Exclusion in Navigation Fallback:**
|
||||
- *Decision:* Explicitly exclude `_framework`, `images`, `css`, `js`, and `lib` directories from navigation fallback rewriting.
|
||||
- *Rationale:* Prevents corrupted binary downloads (such as `.wasm` or missing images) from accidentally serving `index.html` content with invalid MIME types.
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
#### 1. Add `ZeroSpace.Web/wwwroot/staticwebapp.config.json`
|
||||
Configure the Azure Static Web Apps routing engine:
|
||||
```json
|
||||
{
|
||||
"navigationFallback": {
|
||||
"rewrite": "/index.html",
|
||||
"exclude": [
|
||||
"/images/*",
|
||||
"/css/*",
|
||||
"/js/*",
|
||||
"/lib/*",
|
||||
"/_framework/*",
|
||||
"/*.ico",
|
||||
"/*.png",
|
||||
"/*.json"
|
||||
]
|
||||
},
|
||||
"responseOverrides": {
|
||||
"404": {
|
||||
"rewrite": "/index.html"
|
||||
}
|
||||
},
|
||||
"mimeTypes": {
|
||||
".wasm": "application/wasm",
|
||||
".json": "application/json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Add `ZeroSpace.Web/wwwroot/404.html`
|
||||
Add lightweight SPA 404 redirect handler for static hosts:
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ZeroSpace</title>
|
||||
<script type="text/javascript">
|
||||
var pathSegmentsToKeep = 0;
|
||||
var l = window.location;
|
||||
l.replace(
|
||||
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
|
||||
l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
|
||||
l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
|
||||
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
|
||||
l.hash
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
#### 3. Update `ZeroSpace.Web/wwwroot/index.html`
|
||||
Add the URL reconstruction handler before Blazor script startup in `<head>`:
|
||||
```html
|
||||
<script type="text/javascript">
|
||||
(function(l) {
|
||||
if (l.search[1] === '/' ) {
|
||||
var decoded = l.search.slice(1).split('&').map(function(s) {
|
||||
return s.replace(/~and~/g, '&')
|
||||
}).join('?');
|
||||
window.history.replaceState(null, null,
|
||||
l.pathname.slice(0, -1) + decoded + l.hash
|
||||
);
|
||||
}
|
||||
}(window.location))
|
||||
</script>
|
||||
```
|
||||
|
||||
### File Structure
|
||||
- `ZeroSpace.Web/`
|
||||
- `wwwroot/`
|
||||
- `staticwebapp.config.json` *(new)*
|
||||
- `404.html` *(new)*
|
||||
- `index.html` *(modified)*
|
||||
|
||||
### Risks & Mitigations
|
||||
- **Static Asset Masking:** If asset routes are mistakenly rewritten to `index.html`, WASM or image loads fail silently.
|
||||
- *Mitigation:* Explicit glob exclusions in `staticwebapp.config.json` for `/_framework/*`, `/images/*`, `/css/*`, and asset extensions.
|
||||
- **Route Guard Interaction:** Unreleased pages should still respect release restrictions.
|
||||
- *Mitigation:* `ReleaseGuard.razor` continues to evaluate `SiteMap.IsReleased(pageType)` after router loads, gracefully redirecting unreleased routes to `/galaxy`.
|
||||
|
||||
# Testing
|
||||
|
||||
### Validation Approach
|
||||
Verification focuses on confirming that published artifacts contain all necessary configuration files, that the build succeeds without error, and that URL restoration logic accurately handles routes, query strings, and asset exclusions.
|
||||
|
||||
### Key Scenarios
|
||||
- **Direct Route Navigation:** Direct GET to `/galaxy` serves the application shell and initializes Blazor at `/galaxy`.
|
||||
- **Deep Item Route Navigation:** Direct GET to `/planetary-mastery-items` or `/StarSystem` routes directly to the requested component.
|
||||
- **Static Asset Serving:** Requests to `/_framework/blazor.webassembly.js`, `/images/planetary-mastery-items/Battery.png`, and `/css/app.css` return the physical static files directly with correct MIME types.
|
||||
- **Query Parameter Preservation:** Direct URL with queries (e.g. `/galaxy?filter=core`) retains the query parameters after URL reconstruction.
|
||||
|
||||
### Test Changes
|
||||
- Execute `dotnet build ZeroSpace.sln` to ensure all projects build cleanly.
|
||||
- Execute `dotnet publish ZeroSpace.Web/ZeroSpace.Web.csproj -c Release` and inspect the output directory to confirm `staticwebapp.config.json`, `404.html`, and `index.html` are copied to `publish/wwwroot`.
|
||||
|
||||
# Delivery Steps
|
||||
|
||||
### Step 1: Configure Azure Static Web Apps navigation fallback
|
||||
Azure Static Web Apps routes direct SPA page requests to `/index.html` while preserving direct access to static assets.
|
||||
|
||||
- Create `ZeroSpace.Web/wwwroot/staticwebapp.config.json` with `navigationFallback.rewrite` set to `/index.html`.
|
||||
- Add route exclusions for static assets (`/images/*`, `/css/*`, `/js/*`, `/lib/*`, `/_framework/*`, and common file extensions).
|
||||
- Define MIME type overrides for `.wasm` and `.json` to ensure optimal loading performance.
|
||||
|
||||
### Step 2: Implement universal 404 SPA redirect and URL reconstruction
|
||||
Static hosts without native rewrite capabilities redirect deep link 404s back to `index.html` where the original URL path is reconstructed seamlessly.
|
||||
|
||||
- Add `ZeroSpace.Web/wwwroot/404.html` containing the lightweight SPA redirect script that converts deep URL paths into query parameters.
|
||||
- Update `ZeroSpace.Web/wwwroot/index.html` `<head>` section with the matching URL restoration script using `history.replaceState` before the Blazor WebAssembly runtime initializes.
|
||||
- Ensure query strings and route hash fragments are preserved intact during URL reconstruction.
|
||||
|
||||
### Step 3: Validate publish output and build verification
|
||||
The project builds and publishes cleanly with all fallback and redirect assets bundled in the output `wwwroot`.
|
||||
|
||||
- Run `dotnet build ZeroSpace.sln` to confirm compilation integrity.
|
||||
- Run `dotnet publish ZeroSpace.Web/ZeroSpace.Web.csproj -c Release` to verify that `staticwebapp.config.json`, `404.html`, and `index.html` are correctly packaged into the published output directory.
|
||||
- Verify that `ZeroSpace.Deploy/Program.cs` can deploy the published `wwwroot` artifact containing the fallback configurations.
|
||||
Reference in New Issue
Block a user