The frontend is configured through environment variables. The canonical list and
defaults live in
frontend/.env.example.
Build-time vs runtime
Section titled “Build-time vs runtime”This is the most important distinction:
VITE_*variables are inlined at build time. They are baked into the JavaScript bundle whenvite buildruns. In practice you set them infrontend/.envfor local development (the Vite dev server reads them); the published image bakes only deployment-neutral values.- Deploy-time values come from the runtime
/config.js. In production the backend renders/config.jsfrom itsfrontend.*configuration (see Backend Configuration), settingwindow.__VIBEXP_ENV__before the SPA bundle runs. The MCP endpoint and analytics are injected this way — changing them needs a restart, not a rebuild. In local dev there is no backend-rendered/config.js(the request 404s harmlessly) and the app falls back to the build-timeimport.meta.envvalues.
Backend API
Section titled “Backend API”| Variable | Default | Notes |
|---|---|---|
VITE_API_BASE_URL |
/api/v1 (image build) |
Backend API base, including version prefix. Leave empty/relative for same-origin requests (the combined image). The local-dev .env.example points it at http://localhost:8080/api/v1, targeting make backend-run-dev. |
Release stamps
Section titled “Release stamps”Build-time only, set by the release pipeline (build args in
backend/Dockerfile); shown in the UI for support/debugging.
| Variable | Default | Notes |
|---|---|---|
VITE_RELEASE_SHA |
dev |
Commit SHA of the build. release.yml passes github.sha. |
VITE_RELEASE_DATE |
unknown |
Build date stamp. |
Branding
Section titled “Branding”Company branding is not a VITE_* variable. Since v0.15.0 the name, logo and
support and legal links are the instance’s site info, which an instance
admin edits in the admin area: see
Site Info (Branding).
The backend inlines the eight values into the same /config.js, as
window.__VIBEXP_SITE_INFO__, so the first paint is already branded, and
serves them again at GET /api/v1/site-info. Components read them through the
useSiteInfo() hook, never from getEnv(). In local dev, where there is no
backend-rendered /config.js, the app starts unbranded.
| Variable | Notes |
|---|---|
VITE_MCP_ENDPOINT |
The MCP endpoint advertised in client-setup snippets, e.g. https://<your-mcp-host>/mcp/v1/common. Runtime-injectable via frontend.mcp_endpoint. |
Error reporting / problem details
Section titled “Error reporting / problem details”| Variable | Notes |
|---|---|
VITE_ERROR_TYPE_BASE_URI |
Base URI for building RFC 9457 problem-detail type fields client-side (e.g. <base>/errors/UNKNOWN). Empty falls back to about:blank. |
Analytics (Google Tag Manager / GA4)
Section titled “Analytics (Google Tag Manager / GA4)”Off by default: set a container ID to opt in. Runtime-injectable via the
backend’s frontend.gtm_id / frontend.ga4_measurement_id config.
| Variable | Default | Notes |
|---|---|---|
VITE_GTM_ID |
— | GTM container ID (e.g. GTM-XXXXXXX). Setting it is the opt-in: GTM loads only when it is non-empty. There is no separate enable flag. |
VITE_GA4_MEASUREMENT_ID |
— | GA4 Measurement ID (e.g. G-XXXXXXXXXX) for client-ID capture. |
VibeXP ships no cookie-consent gate of its own: once an ID is set, the tag loads unconditionally. If your deployment needs Consent Mode, configure it inside your own GTM container.
Web push (removed)
Section titled “Web push (removed)”Browser push notifications (Firebase Cloud Messaging) were removed in
v0.9.0 along with the seven VITE_FIREBASE_* variables.
src/utils/serviceWorker.ts and public/{sw,dev-sw}.js still exist solely to
evict legacy workers from returning browsers.