How to deploy Vue app to Azure
Azure Static Web Apps provides serverless hosting for Vue applications with automatic builds, global CDN, and integrated API support. As the creator of CoreUI with 12 years of Vue.js development experience, I’ve deployed hundreds of Vue applications to Azure, serving millions of users with enterprise-grade security, custom authentication, and seamless Azure Functions integration.
The fastest approach uses Azure Static Web Apps with GitHub Actions for automatic deployments.
Create Static Web App
# Install Azure CLI
brew install azure-cli # macOS
# or download from https://aka.ms/installazurecliwindows
# Login to Azure
az login
# Create resource group
az group create \
--name my-vue-app-rg \
--location eastus
# Create static web app
az staticwebapp create \
--name my-vue-app \
--resource-group my-vue-app-rg \
--source https://github.com/username/my-vue-app \
--location eastus \
--branch main \
--app-location "/" \
--output-location "dist"
Configure Build
Create staticwebapp.config.json:
{
"routes": [
{
"route": "/*",
"serve": "/index.html",
"statusCode": 200
}
],
"navigationFallback": {
"rewrite": "/index.html",
"exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
},
"responseOverrides": {
"404": {
"rewrite": "/index.html",
"statusCode": 200
}
},
"globalHeaders": {
"cache-control": "must-revalidate, max-age=3600"
},
"mimeTypes": {
".json": "application/json"
}
}
GitHub Actions Workflow
Azure automatically creates .github/workflows/azure-static-web-apps-*.yml:
name: Azure Static Web Apps CI/CD
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- main
jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Build And Deploy
id: builddeploy
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: "/"
api_location: "api"
output_location: "dist"
close_pull_request_job:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
action: "close"
Environment Variables
Add in Azure Portal:
- Go to Static Web App → Configuration
- Add application settings:
VITE_API_URL:https://api.example.comVITE_API_KEY:your-api-key
Access in Vue:
const apiUrl = import.meta.env.VITE_API_URL
const apiKey = import.meta.env.VITE_API_KEY
Custom Domain
# Add custom domain
az staticwebapp hostname set \
--name my-vue-app \
--resource-group my-vue-app-rg \
--hostname www.example.com
# Validate domain
az staticwebapp hostname show \
--name my-vue-app \
--resource-group my-vue-app-rg \
--hostname www.example.com
Configure DNS:
Type Name Value
CNAME www my-vue-app.azurestaticapps.net
Add API with Azure Functions
Create api/users.js:
module.exports = async function (context, req) {
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
]
context.res = {
status: 200,
headers: {
'Content-Type': 'application/json'
},
body: users
}
}
Call from Vue:
<script setup>
import { ref, onMounted } from 'vue'
const users = ref([])
onMounted(async () => {
const response = await fetch('/api/users')
users.value = await response.json()
})
</script>
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
Authentication
Configure in staticwebapp.config.json:
{
"auth": {
"identityProviders": {
"azureActiveDirectory": {
"registration": {
"openIdIssuer": "https://login.microsoftonline.com/{tenant-id}",
"clientIdSettingName": "AAD_CLIENT_ID",
"clientSecretSettingName": "AAD_CLIENT_SECRET"
}
}
}
},
"routes": [
{
"route": "/admin/*",
"allowedRoles": ["admin"]
}
],
"responseOverrides": {
"401": {
"redirect": "/.auth/login/aad",
"statusCode": 302
}
}
}
Use in Vue:
<script setup>
import { ref, onMounted } from 'vue'
const user = ref(null)
onMounted(async () => {
const response = await fetch('/.auth/me')
const data = await response.json()
user.value = data.clientPrincipal
})
const login = () => {
window.location.href = '/.auth/login/aad'
}
const logout = () => {
window.location.href = '/.auth/logout'
}
</script>
<template>
<div v-if="user">
<p>Welcome {{ user.userDetails }}!</p>
<button @click="logout">Logout</button>
</div>
<button v-else @click="login">Login</button>
</template>
Staging Environments
# Create staging environment
az staticwebapp environment create \
--name my-vue-app \
--resource-group my-vue-app-rg \
--environment-name staging
# Each PR gets preview URL:
# https://my-vue-app-staging.azurestaticapps.net
Best Practice Note
This is how we deploy CoreUI Vue templates to Azure for enterprise hosting with Microsoft integration. Azure Static Web Apps provides automatic deployments, built-in authentication with Azure AD, and seamless Azure Functions integration for serverless APIs. Always configure SPA routing fallback, use environment-specific settings, implement authentication for protected routes, and leverage preview environments for pull requests.
For production applications, consider using CoreUI’s Vue Admin Template which includes Azure deployment configurations.
Related Articles
For other deployment options, check out how to deploy Vue app to AWS Amplify and how to deploy Vue app to Vercel.



