Skip to content

react-monorepo environment

Each app has its own .env (generation copies each apps/*/.env.example). The four files are the same apart from PORT, and landing adds two variables.

apps/admin/.env.example

VariableWhat to set
VITE_APP_API_URL
default http://localhost:5000

Backend base URL. Better Auth lives at ${VITE_APP_API_URL}/auth.

Production: The API's public URL, as a build argument.

Compiled into the bundle. Auth lives at <this>/auth, and requests to it carry the traceparent header.
VITE_APP_LANDING
default http://localhost:3000

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The landing site's origin, e.g. https://example.com, as a build argument.

Every app lists its siblings: they're the trusted redirect targets. The auth app links to its terms and privacy pages.
VITE_APP_AUTH_HOST
default http://localhost:3001

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The auth app's origin, e.g. https://auth.example.com.

Every guard and 401 redirects to <this>/login.
VITE_APP_CLIENT_HOST
default http://localhost:3002

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The client app's origin, e.g. https://app.example.com.

Where the auth app sends people after sign-in by default.
VITE_APP_ADMIN_HOST
default http://localhost:3003

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The admin app's origin, e.g. https://admin.example.com.

PORT
default 3003

This app's own dev port.

Production: Not used: each app's image serves on port 80.

Each app's dev server port (landing 3000, auth 3001, client 3002, admin 3003). Change one and update the sibling VITE_APP_*_HOST values.
VITE_OPENOBSERVE_URL
default https://o2.aurostack.co
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: Your OpenObserve instance, as a build argument.

Telemetry is on only when the URL, org and client token are all set.
VITE_OPENOBSERVE_ORG
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: The project's organization identifier, as a build argument.

VITE_OPENOBSERVE_CLIENT_TOKEN
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: A RUM token, as a build argument.

Where to get it: OpenObserve → Ingestion → RUM.

Public by design (write-only). Never the back ends' ingestion token. The instance must list this origin in ZO_CORS_ALLOWED_ORIGINS.

apps/auth/.env.example

VariableWhat to set
VITE_APP_API_URL
default http://localhost:5000

Backend base URL. Better Auth lives at ${VITE_APP_API_URL}/auth.

Production: The API's public URL, as a build argument.

Compiled into the bundle. Auth lives at <this>/auth, and requests to it carry the traceparent header.
VITE_APP_LANDING
default http://localhost:3000

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The landing site's origin, e.g. https://example.com, as a build argument.

Every app lists its siblings: they're the trusted redirect targets. The auth app links to its terms and privacy pages.
VITE_APP_AUTH_HOST
default http://localhost:3001

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The auth app's origin, e.g. https://auth.example.com.

Every guard and 401 redirects to <this>/login.
VITE_APP_CLIENT_HOST
default http://localhost:3002

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The client app's origin, e.g. https://app.example.com.

Where the auth app sends people after sign-in by default.
VITE_APP_ADMIN_HOST
default http://localhost:3003

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The admin app's origin, e.g. https://admin.example.com.

PORT
default 3001

This app's own dev port.

Production: Not used: each app's image serves on port 80.

Each app's dev server port (landing 3000, auth 3001, client 3002, admin 3003). Change one and update the sibling VITE_APP_*_HOST values.
VITE_OPENOBSERVE_URL
default https://o2.aurostack.co
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: Your OpenObserve instance, as a build argument.

Telemetry is on only when the URL, org and client token are all set.
VITE_OPENOBSERVE_ORG
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: The project's organization identifier, as a build argument.

VITE_OPENOBSERVE_CLIENT_TOKEN
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: A RUM token, as a build argument.

Where to get it: OpenObserve → Ingestion → RUM.

Public by design (write-only). Never the back ends' ingestion token. The instance must list this origin in ZO_CORS_ALLOWED_ORIGINS.

apps/client/.env.example

VariableWhat to set
VITE_APP_API_URL
default http://localhost:5000

Backend base URL. Better Auth lives at ${VITE_APP_API_URL}/auth.

Production: The API's public URL, as a build argument.

Compiled into the bundle. Auth lives at <this>/auth, and requests to it carry the traceparent header.
VITE_APP_LANDING
default http://localhost:3000

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The landing site's origin, e.g. https://example.com, as a build argument.

Every app lists its siblings: they're the trusted redirect targets. The auth app links to its terms and privacy pages.
VITE_APP_AUTH_HOST
default http://localhost:3001

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The auth app's origin, e.g. https://auth.example.com.

Every guard and 401 redirects to <this>/login.
VITE_APP_CLIENT_HOST
default http://localhost:3002

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The client app's origin, e.g. https://app.example.com.

Where the auth app sends people after sign-in by default.
VITE_APP_ADMIN_HOST
default http://localhost:3003

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The admin app's origin, e.g. https://admin.example.com.

PORT
default 3002

This app's own dev port.

Production: Not used: each app's image serves on port 80.

Each app's dev server port (landing 3000, auth 3001, client 3002, admin 3003). Change one and update the sibling VITE_APP_*_HOST values.
VITE_OPENOBSERVE_URL
default https://o2.aurostack.co
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: Your OpenObserve instance, as a build argument.

Telemetry is on only when the URL, org and client token are all set.
VITE_OPENOBSERVE_ORG
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: The project's organization identifier, as a build argument.

VITE_OPENOBSERVE_CLIENT_TOKEN
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: A RUM token, as a build argument.

Where to get it: OpenObserve → Ingestion → RUM.

Public by design (write-only). Never the back ends' ingestion token. The instance must list this origin in ZO_CORS_ALLOWED_ORIGINS.

apps/landing/.env.example

VariableWhat to set
VITE_APP_API_URL
default http://localhost:5000

Backend base URL. Better Auth lives at ${VITE_APP_API_URL}/auth.

Production: The API's public URL, as a build argument.

Compiled into the bundle. Auth lives at <this>/auth, and requests to it carry the traceparent header.
VITE_APP_LANDING
default http://localhost:3000

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The landing site's origin, e.g. https://example.com, as a build argument.

Every app lists its siblings: they're the trusted redirect targets. The auth app links to its terms and privacy pages.
VITE_APP_AUTH_HOST
default http://localhost:3001

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The auth app's origin, e.g. https://auth.example.com.

Every guard and 401 redirects to <this>/login.
VITE_APP_CLIENT_HOST
default http://localhost:3002

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The client app's origin, e.g. https://app.example.com.

Where the auth app sends people after sign-in by default.
VITE_APP_ADMIN_HOST
default http://localhost:3003

Sibling app origins. All four share one session cookie across subdomains, so these must agree with the backend's BETTER_AUTH_COOKIE_DOMAIN and its trustedOrigins list, or login will appear to succeed and then bounce.

Production: The admin app's origin, e.g. https://admin.example.com.

PORT
default 3000

This app's own dev port.

Production: Not used: each app's image serves on port 80.

Each app's dev server port (landing 3000, auth 3001, client 3002, admin 3003). Change one and update the sibling VITE_APP_*_HOST values.
VITE_APP_SITE_URL
default http://localhost:3000

Canonical public URL, used for sitemap/robots/OG tags at build time.

Production: The canonical public origin, as a build argument.

Must equal PRODUCTION_ORIGIN in src/features/seo/routes.ts; any other value builds as noindex with a disallowing robots.txt, so previews can't outrank production.
VITE_APP_SUPPORT_EMAIL
default support@example.com

Canonical public URL, used for sitemap/robots/OG tags at build time.

Production: A monitored security and support address, as a build argument.

Published in /.well-known/security.txt; empty skips the file.
VITE_OPENOBSERVE_URL
default https://o2.aurostack.co
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: Your OpenObserve instance, as a build argument.

Telemetry is on only when the URL, org and client token are all set.
VITE_OPENOBSERVE_ORG
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: The project's organization identifier, as a build argument.

VITE_OPENOBSERVE_CLIENT_TOKEN
empty by default
feature telemetry

OpenObserve browser monitoring (RUM): page views, errors, slow requests, and trace headers on API calls. Leave empty and it stays off. The client token is a RUM token (OpenObserve → Ingestion → RUM): write-only and meant to ship in the bundle — never the backend's ingestion token. The instance must list this app's origin in ZO_CORS_ALLOWED_ORIGINS.

Production: A RUM token, as a build argument.

Where to get it: OpenObserve → Ingestion → RUM.

Public by design (write-only). Never the back ends' ingestion token. The instance must list this origin in ZO_CORS_ALLOWED_ORIGINS.
Variable Where Effect
VITE_APP_ALLOWED_HOSTS any apps/*/.env Comma-separated hostnames the dev server answers beyond localhost (a tunnel, *.lvh.me)
API_DOC_URL, API_DOC_USER, API_DOC_PASSWORD packages/types/.env Where yarn workspace @scope/types gen fetches the OpenAPI document; create this file by hand (or with its secrets script)
INFISICAL_PROJECT_ID, INFISICAL_PATH_PREFIX shell yarn secrets: each workspace pulls from <prefix>/<app> (default prefix /frontend)
API setting Must include
BETTER_AUTH_COOKIE_DOMAIN a parent domain of every app’s host (.example.com)
FRONTEND_HOST, MISC_CORS_ORIGINS every app’s origin (trusted origins and CORS)
SMTP_SUPPORT_EMAIL the same address as landing’s VITE_APP_SUPPORT_EMAIL
better-auth at /auth VITE_APP_API_URL + /auth