This application supports runtime configuration, allowing you to modify backend API URLs after building without needing to rebuild the application.
- Build time: Hardcoded fallback defaults are included in the build
- Runtime: The app loads
/config.jsonon startup with the actual configuration - Priority: Runtime config (
config.json) overrides hardcoded defaults
public/config.json- Runtime configuration (copied todist/config.jsonon build)public/config.json.example- Template for reference
{
"VITE_GRAPHQL_URL": "https://localhost:9446/graphql",
"VITE_AUTH_BASE_URL": "https://localhost:9446/auth",
"VITE_OBSERVABILITY_URL": "https://localhost:9446/icp/observability"
}Edit public/config.json with your backend URLs, then restart the dev server:
{
"VITE_GRAPHQL_URL": "https://localhost:9446/graphql",
"VITE_AUTH_BASE_URL": "https://localhost:9446/auth",
"VITE_OBSERVABILITY_URL": "https://localhost:9446/icp/observability"
}# Build the app
pnpm build
# Edit the config in dist/
nano dist/config.json
# Deploy dist/ folderCreate a docker-entrypoint.sh:
#!/bin/sh
# Generate config.json from environment variables
cat > /usr/share/nginx/html/config.json <<EOF
{
"VITE_GRAPHQL_URL": "${GRAPHQL_URL:-https://localhost:9446/graphql}",
"VITE_AUTH_BASE_URL": "${AUTH_BASE_URL:-https://localhost:9446/auth}",
"VITE_OBSERVABILITY_URL": "${OBSERVABILITY_URL:-https://localhost:9446/icp/observability}"
}
EOF
# Start nginx
nginx -g 'daemon off;'Dockerfile:
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]Run with:
docker run -e GRAPHQL_URL=https://api.prod.com/graphql \
-e AUTH_BASE_URL=https://auth.prod.com/auth \
-e OBSERVABILITY_URL=https://api.prod.com/icp/observability \
my-appapiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.json: |
{
"VITE_GRAPHQL_URL": "https://api.k8s.com/graphql",
"VITE_AUTH_BASE_URL": "https://auth.k8s.com/auth",
"VITE_OBSERVABILITY_URL": "https://api.k8s.com/icp/observability"
}
---
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: nginx
image: my-frontend:latest
volumeMounts:
- name: config
mountPath: /usr/share/nginx/html/config.json
subPath: config.json
volumes:
- name: config
configMap:
name: app-configOpen browser console after app loads - you should see:
✓ Runtime configuration loaded from config.json
If config.json fails to load:
- Falls back to hardcoded defaults in the application
- Shows warning in console:
"Failed to load runtime config, using defaults" - App continues to work with default localhost URLs
Default values:
graphqlUrl: 'https://localhost:9446/graphql';
authBaseUrl: 'https://localhost:9446/auth';
observabilityUrl: 'https://localhost:9446/icp/observability';✅ One build, multiple environments - Build once, deploy everywhere
✅ No rebuild required - Change URLs instantly
✅ DevOps friendly - Easy to configure via ConfigMaps, env vars, or direct file modification
✅ Safe fallbacks - Works even if config.json is missing