Skip to content

Static Web Apps

Azure Static Web Apps (SWA) provides global hosting with built-in CDN for the Microtec ERP Angular micro-frontend applications. Each Angular MFE app gets its own SWA instance per environment, giving independent deployment, custom domain, and configuration management.


Naming Convention

mic-erp-fr-{env}-{app-short-name}-swa
AppShort NameExample (dev)
erp-homeerp-homemic-erp-fr-dev-erp-home-swa
apps-accountingaccountingmic-erp-fr-dev-accounting-swa
apps-hrhrmic-erp-fr-dev-hr-swa
apps-financefinancemic-erp-fr-dev-finance-swa
apps-salessalesmic-erp-fr-dev-sales-swa
apps-purchasepurchasemic-erp-fr-dev-purchase-swa
apps-inventoryinventorymic-erp-fr-dev-inventory-swa
app-distributiondistributionmic-erp-fr-dev-distribution-swa
fixed-assetsfixed-assetsmic-erp-fr-dev-fixed-assets-swa

SKU

EnvironmentSKUFeatures
dev / stageFree0.5 GB storage, 100 GB bandwidth/month
preprod / uatStandard2 GB storage, unlimited bandwidth, custom domains
productionStandardCustom domains, staging environments, managed functions

Free Tier Limitations

The Free tier does not support custom domains with APEX records (bare domain). Use a subdomain (*.microtec-test.com) for dev/stage, or upgrade to Standard for APEX support.


staticwebapp.config.json

Each Angular MFE must include a staticwebapp.config.json at the build output root. This file controls routing, headers, and authentication:

json
{
  "routes": [
    {
      "route": "/api/*",
      "statusCode": 404
    },
    {
      "route": "/*",
      "rewrite": "/index.html"
    }
  ],
  "responseOverrides": {
    "404": {
      "rewrite": "/index.html",
      "statusCode": 200
    }
  },
  "globalHeaders": {
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY",
    "X-XSS-Protection": "1; mode=block",
    "Referrer-Policy": "strict-origin-when-cross-origin",
    "Permissions-Policy": "camera=(), microphone=(), geolocation=()",
    "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://*.microtec-test.com https://*.microtecstage.com https://*.onlinemicrotec.com.sa"
  },
  "mimeTypes": {
    ".json": "application/json",
    ".wasm": "application/wasm"
  },
  "navigationFallback": {
    "rewrite": "/index.html",
    "exclude": [
      "*.{css,scss,js,ts,map,json,woff,woff2,ttf,eot,svg,ico,png,jpg,jpeg,gif,webp}"
    ]
  }
}

SPA Routing Fallback

The navigationFallback rewrite to index.html is critical for Angular's PathLocationStrategy. Without it, refreshing the browser on any route other than / returns a 404.


Custom Domains

Each SWA in non-dev environments has a custom domain configured:

Appdevstageproduction
erp-home*.microtec-test.com/erp-home*.microtecstage.com/erp-home*.onlinemicrotec.com.sa/erp-home
accounting*.microtec-test.com/accounting*.microtecstage.com/accounting*.onlinemicrotec.com.sa/accounting

In practice, Azure Front Door serves all apps under a single domain and routes to the correct SWA based on path prefix. The SWA's built-in domain is used as the AFD origin.

Bicep Configuration

bicep
resource swa 'Microsoft.Web/staticSites@2022-09-01' = {
  name: '${resourcePrefix}-${appShortName}-swa'
  location: 'eastus2'  // SWA is a global resource; region is metadata only
  sku: {
    name: environment == 'production' || environment == 'uat' ? 'Standard' : 'Free'
    tier: environment == 'production' || environment == 'uat' ? 'Standard' : 'Free'
  }
  properties: {
    stagingEnvironmentPolicy: 'Enabled'
    allowConfigFileUpdates: true
    provider: 'DevOps'
    enterpriseGradeCdnStatus: environment == 'production' ? 'Enabled' : 'Disabled'
  }
}

Deployment via Pipeline

SWA deployment uses the AzureStaticWebApp@0 task:

yaml
# From unified-frontend-pipeline.yml (SWA deploy step)
- task: AzureStaticWebApp@0
  displayName: 'Deploy $(projectName) to SWA'
  inputs:
    azure_static_web_apps_api_token: $(swaDeployToken)
    app_location: 'FrontApps'
    output_location: 'dist/$(projectName)'
    skip_app_build: true          # Build already done in matrix strategy
    deployment_environment: $(environment)
  env:
    AZURE_STATIC_WEB_APPS_API_TOKEN: $(swaDeployToken)

The swaDeployToken is a per-SWA deployment token stored in the Azure DevOps variable group for each environment. It is not stored in Key Vault (it is a pipeline-only secret).


Environment-Specific Builds

Each Angular app is built with the correct --configuration flag for the target environment:

EnvironmentAngular ConfigAPI Base URL
devdevelopmenthttps://gateway.microtec-test.com
stagestagehttps://gateway.microtecstage.com
preprodpreprodhttps://gateway.microtec-preprod.com
uatuathttps://gateway.microtec-uat.com
productionprodhttps://gateway.onlinemicrotec.com.sa
bash
# Build command per environment
ng build apps-accounting --configuration=stage --output-path=dist/apps-accounting

The angular.json fileReplacements array swaps environment.ts for the target-specific file.


Staging Environments (Production Only)

The Standard SKU in production allows up to 10 staging environments per SWA. These are used for PR previews:

yaml
# PR preview deployment
- task: AzureStaticWebApp@0
  inputs:
    deployment_environment: 'pr-$(System.PullRequest.PullRequestNumber)'

PR preview URLs follow the pattern:

https://{swa-name}-{pr-number}.{region}.azurestaticapps.net

Staging environments are automatically deleted when the PR is closed.


Cache Headers

SWA respects the Cache-Control headers set during blob upload. The pipeline sets:

File PatternCache-Control
index.htmlno-cache, no-store, must-revalidate
*.js, *.cssmax-age=31536000, immutable (1 year, content-hashed)
*.jsonno-cache
assets/*max-age=86400 (1 day)

Troubleshooting

SymptomLikely CauseResolution
404 on page refreshnavigationFallback missing in configVerify staticwebapp.config.json is in build output
Wrong API URL in deployed appWrong --configuration flag usedCheck pipeline environment parameter mapping
Deployment token expiredSWA token rotatedRegenerate token in Azure Portal → SWA → Manage Deployment Token; update ADO variable group
CSP blocking Keycloakconnect-src missing auth domainUpdate Content-Security-Policy in staticwebapp.config.json
SWA deploy task failsswaDeployToken not in variable groupCheck ADO variable group for swaDeployToken variable

Internal Documentation — Microtec Platform Team