用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/fabioc-aloha/Alex_Skill_Mall --skill azure-swa-gotchas命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | azure-swa-gotchas |
| description | Time saved: 2-4 hours per issue |
| lastReviewed | 2026-04-30T00:00:00.000Z |
Time saved: 2-4 hours per issue
Azure Static Web Apps is powerful but has numerous edge cases that cause silent failures or confusing behavior. The documentation covers the happy path; these are the unhappy paths.
Symptom: Login callbacks return 401 → infinite redirect loop
Cause: /.auth/* routes must be explicitly allowed for anonymous BEFORE any /* wildcard with authenticated.
Solution:
{
"routes": [
{ "route": "/.auth/*", "allowedRoles": ["anonymous"] },
{ "route": "/*", "allowedRoles": ["authenticated"] }
]
}
Time saved: 1-2 hours
Symptom: Your linked Function App returns 404, but embedded Functions work
Cause: If the workflow has api_location:, SWA deploys embedded Functions which override any linked backend.
Solution: Remove api_location from workflow to route to the linked Function App.
# Remove this line:
# api_location: "api"
Time saved: 1-2 hours
Symptom: CLI reports success but nothing uploads
Cause: Known bug in v2.0.8
Solution: Use GitHub Actions (Azure/static-web-apps-deploy@v1) instead.
- uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
action: "upload"
app_location: "/"
output_location: "dist"
Time saved: 30-60 min
Symptom: Auth works on default hostname, fails on custom domain
Cause: Entra ID app registration must include callback URIs for BOTH the default SWA hostname AND any custom domain.
Solution: Add both to app registration:
https://yourapp.azurestaticapps.net/.auth/login/aad/callbackhttps://yourdomain.com/.auth/login/aad/callbackTime saved: 30-60 min
Symptom: ManagedIdentityCredential fails in embedded Functions
Cause: Embedded Functions don't have the managed identity environment variables.
Solution: Create a standalone Function App with system-assigned managed identity, link via az staticwebapp backends link.
az staticwebapp backends link \
--name my-swa \
--resource-group my-rg \
--backend-resource-id /subscriptions/.../Microsoft.Web/sites/my-func-app \
--backend-region eastus
Time saved: 2-3 hours
Symptom: SWA content won't load in an iframe
Cause: Default X-Frame-Options is DENY.
Solution: Set SAMEORIGIN in staticwebapp.config.json:
{
"globalHeaders": {
"X-Frame-Options": "SAMEORIGIN"
}
}
Time saved: 30 min
Symptom: New file in public/ doesn't appear on site
Cause: Files in public/ are copied to dist/ during build. Committing doesn't serve them.
Solution: Rebuild and redeploy:
npm run build
# Then trigger deployment
Time saved: 30 min
Symptom: Deployment conflicts or stale content
Cause: Previous deployment source still linked
Solution: Disconnect before moving to CLI or new workflow:
az staticwebapp disconnect --name my-swa
Time saved: 30 min
Symptom: Functions silently fail to deploy
Cause: package.json must have "main" pointing to the file that registers functions via app.http().
Solution:
{
"main": "dist/index.js"
}
Where index.js contains:
const { app } = require('@azure/functions');
app.http('myFunction', { ... });
Time saved: 1-2 hours
Symptom: Using wrong hostname in configuration
Cause: SWA hostnames can change, especially after region changes
Solution: Always verify:
az staticwebapp show --name my-swa --query defaultHostname -o tsv
Time saved: 15 min
Symptom: CDN scripts blocked, CSP violations
Cause: Enterprise environments block external CDNs, tracking prevention enabled
Solution: Self-host all JavaScript libraries in your public/ folder.
Time saved: 1-2 hours + avoids security review
Symptom: Long API calls silently drop
Cause: Browsers may kill connections without explicit timeout
Solution:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 180000); // 3 min
try {
const response = await fetch(url, { signal: controller.signal });
// ...
} finally {
clearTimeout(timeoutId);
}
Time saved: 1-2 hours debugging "random" failures
entra-redirect-uris — More auth gotchasvite-public-rebuild — Build system details基于 SOC 职业分类