Static Route Overrides

Inject dynamic responses at specific file paths under a static directory.

Prerequisites: see Introduction.

Full source

<#
    Sample Kestrun Server on how to use static routes.
    These examples demonstrate how to configure static routes in a Kestrun server.
    FileName: 3.3-Static-OverrideRoutes.ps1
#>

# Import the Kestrun module
Install-PSResource -Name Kestrun

# Initialize Kestrun root directory
# the default value is $PWD
# This is recommended in order to use relative paths without issues
Initialize-KrRoot -Path $PSScriptRoot

# Create a new Kestrun server
New-KrServer -Name "Simple Server"

# Add a listener on port 5000 and IP address 127.0.0.1 (localhost)
Add-KrListener -Port 5000 -IPAddress ([IPAddress]::Loopback)

# Add the PowerShell runtime
# !!!!Important!!!! this step is required to process PowerShell routes and middlewares
Add-KrPowerShellRuntime

# Add a static files service
Add-KrStaticFilesService -RequestPath '/assets' -RootPath '.\Assets\wwwroot'

# Add a static map override
Add-KrStaticMapOverride -Path '/assets/override/pwsh' -ScriptBlock {

    $data = @{
        status  = 'ok'
        message = 'Static override works!'
    }

    Write-KrJsonResponse -InputObject $data
}

# Enable Kestrun configuration
Enable-KrConfiguration

# Start the server asynchronously
Start-KrServer

IMPORTANT – Order Matters

Overrides must be registered before Enable-KrConfiguration. After configuration is enabled the internal route / static map is frozen; calling Add-KrStaticMapOverride afterward will throw an exception.

Step-by-step

  1. Standard setup: module install, root initialization, server, listener.
  2. Runtime: Add-KrPowerShellRuntime enables execution of PowerShell script block overrides.
  3. Static service: Add-KrStaticFilesService mounts /assets to serve physical files.
  4. Override: Add-KrStaticMapOverride -Path '/assets/override/pwsh' injects a dynamic GET endpoint that returns JSON instead of serving a physical file if one exists at that path.
  5. Configuration: Enable-KrConfiguration finalizes registration; changes after this (for overrides) are not allowed.
  6. Serve: Start-KrServer begins accepting requests.

Why use an override?

  • Add a health or status JSON under a static prefix (e.g., /assets/status).
  • Replace a generated config file without changing the build output.
  • Rapid prototyping: deliver dynamic snippets alongside static SPA assets.

Behavior and precedence

  • Path match is exact against the full request path.
  • An override takes precedence over a file of the same path under the static root.
  • If no override exists the physical file (if present) is served.

Try it

Start the server

. .\docs\pwsh\tutorial\examples\3.3-Static-OverrideRoutes.ps1

Request the overridden path

curl http://127.0.0.1:5000/assets/override/pwsh
Invoke-RestMethod -Uri 'http://127.0.0.1:5000/assets/override/pwsh'

Expected JSON:

{ "status": "ok", "message": "Static override works!" }

(Optional) Create a file to test precedence

Create a physical file at Assets/wwwroot/override/pwsh and restart the script. The override still wins. Remove the override line (or comment it out), restart, and the physical file will be served instead.

Best practices

  • Keep override script blocks small and fast (avoid long-running logic).
  • Use descriptive paths (e.g., /assets/health, /assets/meta/info).
  • Avoid large dynamic payloads; prefer a dedicated API route (Add-KrMapRoute) for complex behavior.
  • Document override locations so future maintainers understand why a file path is dynamic.

Troubleshooting

Symptom Cause Fix
Exception when adding override Added after Enable-KrConfiguration Move Add-KrStaticMapOverride earlier (before enabling).
404 Not Found Path mismatch or missing static base Verify path starts with mounted prefix /assets and static service registered.
Physical file served instead of JSON Override removed or path typo Re-add override with correct path; ensure leading /.
Unexpected content type Response helper not used Use Write-KrJsonResponse / Write-KrTextResponse as appropriate.

When to choose an override vs a normal route

Scenario Override (Add-KrStaticMapOverride) Standard route (Add-KrMapRoute)
Integrate dynamic JSON under static prefix Possible (but separate path tree)
Need route outside static prefix ✖ (not needed)
Replace/augment a single file path Indirect (different URL)
Many related dynamic endpoints Less ideal ✔ (group them normally)

Cmdlet references


Next

Previous: File Server & Directory Browsing
Next: Adding a Favicon
Skip ahead: Variable Routes