staticwebapp.config.json runs at the edge of an Azure Static Web App — before your app code. It decides who can reach which route, where unmatched paths go, and what your error pages look like.
Route rules: auth, redirects, rewrites
Each route can require a role, redirect, or rewrite:
"routes": [
{ "route": "/admin/*", "allowedRoles": ["administrator"] },
{ "route": "/login", "rewrite": "/.auth/login/aad" },
{ "route": "/old-path", "redirect": "/new-path", "statusCode": 301 }
]
allowedRoles is enforced at the edge — stronger than checking auth in client JS alone.
Fix the SPA refresh 404
Single-page-app routes are not files, so a refresh on /dashboard 404s unless you fall back to the shell:
"navigationFallback": {
"rewrite": "/index.html",
"exclude": ["/images/*.{png,jpg,gif}", "/css/*", "/js/*"]
}
The exclude list is essential — without it, a missing image would also return your HTML.
Custom error pages
responseOverrides turns raw status codes into friendly pages or redirects:
"responseOverrides": {
"401": { "redirect": "/login", "statusCode": 302 },
"404": { "rewrite": "/404.html" }
}
Security headers everywhere
Put Content-Security-Policy and X-Content-Type-Options in globalHeaders so they apply to every response.
Security notes
- Return 404 (not 403) for protected admin routes so their existence is not revealed.
- Auth provider secrets go in application settings, never in this file.
Open the Static Web App config template and ask the workspace to "add a route that requires the authenticated role" or "add a Content-Security-Policy header", then diff the result.