{"id":"444390e2-5f3a-4b52-9e90-89cde4f5d70e","shortId":"NEABCK","kind":"skill","title":"Azure Static Web Apps","tagline":"Awesome Copilot skill by Github","description":"## Overview\n\nAzure Static Web Apps (SWA) hosts static frontends with optional serverless API backends. The SWA CLI (`swa`) provides local development emulation and deployment capabilities.\n\n**Key features:**\n- Local emulator with API proxy and auth simulation\n- Framework auto-detection and configuration\n- Direct deployment to Azure\n- Database connections support\n\n**Config files:**\n- `swa-cli.config.json` - CLI settings, **created by `swa init`** (never create manually)\n- `staticwebapp.config.json` - Runtime config (routes, auth, headers, API runtime) - can be created manually\n\n## General Instructions\n\n### Installation\n\n```bash\nnpm install -D @azure/static-web-apps-cli\n```\n\nVerify: `npx swa --version`\n\n### Quick Start Workflow\n\n**IMPORTANT: Always use `swa init` to create configuration files. Never manually create `swa-cli.config.json`.**\n\n1. `swa init` - **Required first step** - auto-detects framework and creates `swa-cli.config.json`\n2. `swa start` - Run local emulator at `http://localhost:4280`\n3. `swa login` - Authenticate with Azure\n4. `swa deploy` - Deploy to Azure\n\n### Configuration Files\n\n**swa-cli.config.json** - Created by `swa init`, do not create manually:\n- Run `swa init` for interactive setup with framework detection\n- Run `swa init --yes` to accept auto-detected defaults\n- Edit the generated file only to customize settings after initialization\n\nExample of generated config (for reference only):\n```json\n{\n  \"$schema\": \"https://aka.ms/azure/static-web-apps-cli/schema\",\n  \"configurations\": {\n    \"app\": {\n      \"appLocation\": \".\",\n      \"apiLocation\": \"api\",\n      \"outputLocation\": \"dist\",\n      \"appBuildCommand\": \"npm run build\",\n      \"run\": \"npm run dev\",\n      \"appDevserverUrl\": \"http://localhost:3000\"\n    }\n  }\n}\n```\n\n**staticwebapp.config.json** (in app source or output folder) - This file CAN be created manually for runtime configuration:\n```json\n{\n  \"navigationFallback\": {\n    \"rewrite\": \"/index.html\",\n    \"exclude\": [\"/images/*\", \"/css/*\"]\n  },\n  \"routes\": [\n    { \"route\": \"/api/*\", \"allowedRoles\": [\"authenticated\"] }\n  ],\n  \"platform\": {\n    \"apiRuntime\": \"node:20\"\n  }\n}\n```\n\n## Command-line Reference\n\n### swa login\n\nAuthenticate with Azure for deployment.\n\n```bash\nswa login                              # Interactive login\nswa login --subscription-id <id>       # Specific subscription\nswa login --clear-credentials          # Clear cached credentials\n```\n\n**Flags:** `--subscription-id, -S` | `--resource-group, -R` | `--tenant-id, -T` | `--client-id, -C` | `--client-secret, -CS` | `--app-name, -n`\n\n### swa init\n\nConfigure a new SWA project based on an existing frontend and (optional) API. Detects frameworks automatically.\n\n```bash\nswa init                    # Interactive setup\nswa init --yes              # Accept defaults\n```\n\n### swa build\n\nBuild frontend and/or API.\n\n```bash\nswa build                   # Build using config\nswa build --auto            # Auto-detect and build\nswa build myApp             # Build specific configuration\n```\n\n**Flags:** `--app-location, -a` | `--api-location, -i` | `--output-location, -O` | `--app-build-command, -A` | `--api-build-command, -I`\n\n### swa start\n\nStart local development emulator.\n\n```bash\nswa start                                    # Serve from outputLocation\nswa start ./dist                             # Serve specific folder\nswa start http://localhost:3000              # Proxy to dev server\nswa start ./dist --api-location ./api        # With API folder\nswa start http://localhost:3000 --run \"npm start\"  # Auto-start dev server\n```\n\n**Common framework ports:**\n| Framework | Port |\n|-----------|------|\n| React/Vue/Next.js | 3000 |\n| Angular | 4200 |\n| Vite | 5173 |\n\n**Key flags:**\n- `--port, -p` - Emulator port (default: 4280)\n- `--api-location, -i` - API folder path\n- `--api-port, -j` - API port (default: 7071)\n- `--run, -r` - Command to start dev server\n- `--open, -o` - Open browser automatically\n- `--ssl, -s` - Enable HTTPS\n\n### swa deploy\n\nDeploy to Azure Static Web Apps.\n\n```bash\nswa deploy                              # Deploy using config\nswa deploy ./dist                       # Deploy specific folder\nswa deploy --env production             # Deploy to production\nswa deploy --deployment-token <TOKEN>   # Use deployment token\nswa deploy --dry-run                    # Preview without deploying\n```\n\n**Get deployment token:**\n- Azure Portal: Static Web App → Overview → Manage deployment token\n- CLI: `swa deploy --print-token`\n- Environment variable: `SWA_CLI_DEPLOYMENT_TOKEN`\n\n**Key flags:**\n- `--env` - Target environment (`preview` or `production`)\n- `--deployment-token, -d` - Deployment token\n- `--app-name, -n` - Azure SWA resource name\n\n### swa db\n\nInitialize database connections.\n\n```bash\nswa db init --database-type mssql\nswa db init --database-type postgresql\nswa db init --database-type cosmosdb_nosql\n```\n\n## Scenarios\n\n### Create SWA from Existing Frontend and Backend\n\n**Always run `swa init` before `swa start` or `swa deploy`. Do not manually create `swa-cli.config.json`.**\n\n```bash\n# 1. Install CLI\nnpm install -D @azure/static-web-apps-cli\n\n# 2. Initialize - REQUIRED: creates swa-cli.config.json with auto-detected settings\nnpx swa init              # Interactive mode\n# OR\nnpx swa init --yes        # Accept auto-detected defaults\n\n# 3. Build application (if needed)\nnpm run build\n\n# 4. Test locally (uses settings from swa-cli.config.json)\nnpx swa start\n\n# 5. Deploy\nnpx swa login\nnpx swa deploy --env production\n```\n\n### Add Azure Functions Backend\n\n1. **Create API folder:**\n```bash\nmkdir api && cd api\nfunc init --worker-runtime node --model V4\nfunc new --name message --template \"HTTP trigger\"\n```\n\n2. **Example function** (`api/src/functions/message.js`):\n```javascript\nconst { app } = require('@azure/functions');\n\napp.http('message', {\n    methods: ['GET', 'POST'],\n    authLevel: 'anonymous',\n    handler: async (request) => {\n        const name = request.query.get('name') || 'World';\n        return { jsonBody: { message: `Hello, ${name}!` } };\n    }\n});\n```\n\n3. **Set API runtime** in `staticwebapp.config.json`:\n```json\n{\n  \"platform\": { \"apiRuntime\": \"node:20\" }\n}\n```\n\n4. **Update CLI config** in `swa-cli.config.json`:\n```json\n{\n  \"configurations\": {\n    \"app\": { \"apiLocation\": \"api\" }\n  }\n}\n```\n\n5. **Test locally:**\n```bash\nnpx swa start ./dist --api-location ./api\n# Access API at http://localhost:4280/api/message\n```\n\n**Supported API runtimes:** `node:18`, `node:20`, `node:22`, `dotnet:8.0`, `dotnet-isolated:8.0`, `python:3.10`, `python:3.11`\n\n### Set Up GitHub Actions Deployment\n\n1. **Create SWA resource** in Azure Portal or via Azure CLI\n2. **Link GitHub repository** - workflow auto-generated, or create manually:\n\n`.github/workflows/azure-static-web-apps.yml`:\n```yaml\nname: Azure Static Web Apps CI/CD\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    types: [opened, synchronize, reopened, closed]\n    branches: [main]\n\njobs:\n  build_and_deploy:\n    if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Build And Deploy\n        uses: Azure/static-web-apps-deploy@v1\n        with:\n          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}\n          repo_token: ${{ secrets.GITHUB_TOKEN }}\n          action: upload\n          app_location: /\n          api_location: api\n          output_location: dist\n\n  close_pr:\n    if: github.event_name == 'pull_request' && github.event.action == 'closed'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: Azure/static-web-apps-deploy@v1\n        with:\n          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}\n          action: close\n```\n\n3. **Add secret:** Copy deployment token to repository secret `AZURE_STATIC_WEB_APPS_API_TOKEN`\n\n**Workflow settings:**\n- `app_location` - Frontend source path\n- `api_location` - API source path\n- `output_location` - Built output folder\n- `skip_app_build: true` - Skip if pre-built\n- `app_build_command` - Custom build command\n\n## Troubleshooting\n\n| Issue | Solution |\n|-------|----------|\n| 404 on client routes | Add `navigationFallback` with `rewrite: \"/index.html\"` to `staticwebapp.config.json` |\n| API returns 404 | Verify `api` folder structure, ensure `platform.apiRuntime` is set, check function exports |\n| Build output not found | Verify `output_location` matches actual build output directory |\n| Auth not working locally | Use `/.auth/login/<provider>` to access auth emulator UI |\n| CORS errors | APIs under `/api/*` are same-origin; external APIs need CORS headers |\n| Deployment token expired | Regenerate in Azure Portal → Static Web App → Manage deployment token |\n| Config not applied | Ensure `staticwebapp.config.json` is in `app_location` or `output_location` |\n| Local API timeout | Default is 45 seconds; optimize function or check for blocking calls |\n\n**Debug commands:**\n```bash\nswa start --verbose log        # Verbose output\nswa deploy --dry-run           # Preview deployment\nswa --print-config             # Show resolved configuration\n```","tags":["azure","static","web","apps","awesome","copilot","github"],"capabilities":["skill","source-github","category-awesome-copilot"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/azure-static-web-apps","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under github/awesome-copilot","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T14:40:17.548Z","embedding":null,"createdAt":"2026-04-18T20:25:50.626Z","updatedAt":"2026-04-22T14:40:17.548Z","lastSeenAt":"2026-04-22T14:40:17.548Z","tsv":"'/.auth/login':1025 '/api':239,411,768,1035 '/azure/static-web-apps-cli/schema':195 '/css':236 '/dist':393,407,493,764 '/images':235 '/index.html':233,991 '1':110,618,682,798 '18':778 '2':123,625,706,809 '20':245,745,780 '22':782 '3':132,650,735,933 '3.10':790 '3.11':792 '3000':213,400,418,433 '4':138,658,746 '404':983,996 '4200':435 '4280':131,445 '4280/api/message':773 '45':1075 '5':668,757 '5173':437 '7071':460 '8.0':784,788 'accept':169,328,645 'access':769,1027 'action':796,889,931 'actions/checkout':863 'actual':1016 'add':678,934,987 'aka.ms':194 'aka.ms/azure/static-web-apps-cli/schema':193 'allowedrol':240 'alway':98,602 'and/or':334 'angular':434 'anonym':721 'api':22,40,76,200,316,335,362,375,409,413,447,450,454,457,684,688,690,737,756,766,770,775,877,883,893,895,923,929,946,955,957,994,998,1033,1041,1071 'api-build-command':374 'api-loc':361,408,446,765 'api-port':453 'api/src/functions/message.js':709 'apiloc':199,755 'apiruntim':243,743 'app':4,14,197,216,299,358,370,484,527,559,712,754,826,876,882,891,922,928,945,950,966,974,1054,1065 'app-build-command':369 'app-loc':357 'app-nam':298,558 'app.http':715 'appbuildcommand':203 'appdevserverurl':211 'appli':1060 'applic':652 'apploc':198 'async':723 'auth':43,74,1020,1028 'authent':135,241,252 'authlevel':720 'auto':47,117,171,344,346,423,632,647,815 'auto-detect':46,116,170,345,631,646 'auto-gener':814 'auto-start':422 'automat':319,472 'awesom':5 'azur':1,11,54,137,143,254,481,523,562,679,803,807,823,873,919,942,1050 'azure/functions':714 'azure/static-web-apps-cli':89,624 'azure/static-web-apps-deploy':870,916 'backend':23,601,681 'base':309 'bash':85,257,320,336,385,485,571,617,686,760,1086 'block':1082 'branch':830,839 'browser':471 'build':206,331,332,338,339,343,349,351,353,371,376,651,657,842,866,967,975,978,1008,1017 'built':962,973 'c':293 'cach':275 'call':1083 'capabl':34 'category-awesome-copilot' 'cd':689 'check':1005,1080 'ci/cd':827 'clear':272,274 'clear-credenti':271 'cli':26,61,532,541,620,748,808 'client':291,295,985 'client-id':290 'client-secret':294 'close':838,854,899,907,932 'command':247,372,377,463,976,979,1085 'command-lin':246 'common':427 'config':58,72,187,341,490,749,1058,1103 'configur':50,104,144,196,229,304,355,753,1106 'connect':56,570 'const':711,725 'copi':936 'copilot':6 'cor':1031,1043 'cosmosdb':592 'creat':63,68,80,103,108,121,147,153,225,595,615,628,683,799,818 'credenti':273,276 'cs':297 'custom':180,977 'd':88,555,623 'databas':55,569,576,583,590 'database-typ':575,582,589 'db':567,573,580,587 'debug':1084 'default':173,329,444,459,649,1073 'deploy':33,52,140,141,256,478,479,487,488,492,494,498,501,505,507,510,513,519,521,530,534,542,553,556,611,669,675,797,844,868,937,1045,1056,1094,1099 'deployment-token':506,552 'detect':48,118,163,172,317,347,633,648 'dev':210,403,425,466 'develop':30,383 'direct':51 'directori':1019 'dist':202,898 'dotnet':783,786 'dotnet-isol':785 'dri':515,1096 'dry-run':514,1095 'edit':174 'emul':31,38,128,384,442,1029 'enabl':475 'ensur':1001,1061 'env':499,546,676 'environ':538,548 'error':1032 'exampl':184,707 'exclud':234 'exist':312,598 'expir':1047 'export':1007 'extern':1040 'featur':36 'file':59,105,145,177,222 'first':114 'flag':277,356,439,545 'folder':220,396,414,451,496,685,964,999 'found':1011 'framework':45,119,162,318,428,430 'frontend':18,313,333,599,952 'func':691,699 'function':680,708,1006,1078 'general':82 'generat':176,186,816 'get':520,718 'github':9,795,811 'github.event':846,849,902 'github.event.action':853,906 'github/workflows/azure-static-web-apps.yml':820 'group':284 'handler':722 'header':75,1044 'hello':733 'host':16 'http':704 'https':476 'id':266,280,288,292 'import':97 'init':66,101,112,150,157,166,303,322,326,574,581,588,605,637,643,692 'initi':183,568,626 'instal':84,87,619,622 'instruct':83 'interact':159,260,323,638 'isol':787 'issu':981 'j':456 'javascript':710 'job':841 'json':191,230,741,752 'jsonbodi':731 'key':35,438,544 'latest':860,913 'line':248 'link':810 'local':29,37,127,382,660,759,1023,1070 'localhost':130,212,399,417,772 'locat':359,363,367,410,448,767,892,894,897,951,956,961,1014,1066,1069 'log':1090 'login':134,251,259,261,263,270,672 'main':831,840 'manag':529,1055 'manual':69,81,107,154,226,614,819 'match':1015 'messag':702,716,732 'method':717 'mkdir':687 'mode':639 'model':697 'mssql':578 'myapp':352 'n':301,561 'name':300,560,565,701,726,728,734,822,847,850,865,903 'navigationfallback':231,988 'need':654,1042 'never':67,106 'new':306,700 'node':244,696,744,777,779,781 'nosql':593 'npm':86,204,208,420,621,655 'npx':91,635,641,665,670,673,761 'o':368,469 'open':468,470,835 'optim':1077 'option':20,315 'origin':1039 'output':219,366,896,960,963,1009,1013,1018,1068,1092 'output-loc':365 'outputloc':201,390 'overview':10,528 'p':441 'path':452,954,959 'platform':242,742 'platform.apiruntime':1002 'port':429,431,440,443,455,458 'portal':524,804,1051 'post':719 'postgresql':585 'pr':900 'pre':972 'pre-built':971 'preview':517,549,1098 'print':536,1102 'print-config':1101 'print-token':535 'product':500,503,551,677 'project':308 'provid':28 'proxi':41,401 'pull':832,851,904 'push':829,848 'python':789,791 'quick':94 'r':285,462 'react/vue/next.js':432 'refer':189,249 'regener':1048 'reopen':837 'repo':885 'repositori':812,940 'request':724,833,852,905 'request.query.get':727 'requir':113,627,713 'resolv':1105 'resourc':283,564,801 'resource-group':282 'return':730,995 'rewrit':232,990 'rout':73,237,238,986 'run':126,155,164,205,207,209,419,461,516,603,656,856,909,1097 'runs-on':855,908 'runtim':71,77,228,695,738,776 'same-origin':1037 'scenario':594 'schema':192 'second':1076 'secret':296,935,941 'secrets.azure':879,925 'secrets.github':887 'serv':388,394 'server':404,426,467 'serverless':21 'set':62,181,634,662,736,793,949,1004 'setup':160,324 'show':1104 'simul':44 'skill':7 'skip':965,969 'solut':982 'sourc':217,953,958 'source-github' 'specif':267,354,395,495 'ssl':473 'start':95,125,380,381,387,392,398,406,416,421,424,465,608,667,763,1088 'static':2,12,17,482,525,824,874,880,920,926,943,1052 'staticwebapp.config.json':70,214,740,993,1062 'step':115,861,914 'structur':1000 'subscript':265,268,279 'subscription-id':264,278 'support':57,774 'swa':15,25,27,65,92,100,111,124,133,139,149,156,165,250,258,262,269,302,307,321,325,330,337,342,350,379,386,391,397,405,415,477,486,491,497,504,512,533,540,563,566,572,579,586,596,604,607,610,636,642,666,671,674,762,800,1087,1093,1100 'swa-cli.config.json':60,109,122,146,616,629,664,751 'synchron':836 'target':547 'templat':703 'tenant':287 'tenant-id':286 'test':659,758 'timeout':1072 'token':508,511,522,531,537,543,554,557,878,884,886,888,924,930,938,947,1046,1057 'trigger':705 'troubleshoot':980 'true':968 'type':577,584,591,834 'ubuntu':859,912 'ubuntu-latest':858,911 'ui':1030 'updat':747 'upload':890 'use':99,340,489,509,661,862,869,915,1024 'v1':871,917 'v3':864 'v4':698 'variabl':539 'verbos':1089,1091 'verifi':90,997,1012 'version':93 'via':806 'vite':436 'web':3,13,483,526,825,875,881,921,927,944,1053 'without':518 'work':1022 'worker':694 'worker-runtim':693 'workflow':96,813,948 'world':729 'yaml':821 'yes':167,327,644","prices":[{"id":"b7d37554-2f3d-4354-81a7-ec1b2fc14559","listingId":"444390e2-5f3a-4b52-9e90-89cde4f5d70e","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-04-18T20:25:50.626Z"}],"sources":[{"listingId":"444390e2-5f3a-4b52-9e90-89cde4f5d70e","source":"github","sourceId":"github/awesome-copilot/azure-static-web-apps","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/azure-static-web-apps","isPrimary":false,"firstSeenAt":"2026-04-18T21:48:27.513Z","lastSeenAt":"2026-04-22T12:52:07.073Z"},{"listingId":"444390e2-5f3a-4b52-9e90-89cde4f5d70e","source":"skills_sh","sourceId":"github/awesome-copilot/azure-static-web-apps","sourceUrl":"https://skills.sh/github/awesome-copilot/azure-static-web-apps","isPrimary":true,"firstSeenAt":"2026-04-18T20:25:50.626Z","lastSeenAt":"2026-04-22T14:40:17.548Z"}],"details":{"listingId":"444390e2-5f3a-4b52-9e90-89cde4f5d70e","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"azure-static-web-apps","source":"skills_sh","category":"awesome-copilot","skills_sh_url":"https://skills.sh/github/awesome-copilot/azure-static-web-apps"},"updatedAt":"2026-04-22T14:40:17.548Z"}}