# Environment variables

> Every variable the app reads, which side reads it, and what it is.

Page: https://sdk.chatfuel.com/docs/deploy/environments
Markdown: https://sdk.chatfuel.com/docs/deploy/environments.md

A `VITE_`-prefixed secret is not a secret. Anything with that prefix is compiled into the browser
bundle at build time; everything else is read by the server at runtime. That is why the Chatfuel
token, the Supabase service-role key and the admin password have no prefix — Vite cannot bake them
into the client even in principle.

Keep the build environment and the runtime environment identical. Where they differ, the failure
surfaces at the gate rather than at the mismatch — see
[the rule that catches everyone once](/docs/deploy).

## Always [#always]

| Name                         | Side   | What it is                                                                                                                                          |
| ---------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHATFUEL_TOKEN`             | server | The dashboard token, from [the token page](https://panel.chatfuel.com/integration/auth/token). Read only by the proxy, never sent to the browser.   |
| `VITE_CHATFUEL_WORKSPACE_ID` | client | The workspace the app opens on. Not a fence: every workspace the token's account owns is in the picker. Unused when the `auth` module is installed. |
| `CHATFUEL_API_BASE`          | server | Upstream API base. `https://panel.chatfuel.com` unless you are pointed at a staging environment.                                                    |
| `VITE_APP_NAME`              | client | Browser tab, top bar, sign-in screen.                                                                                                               |
| `VITE_APP_LOGO`              | client | A file in `public/`, or an absolute URL. The tab icon itself is in `index.html` — the head is parsed before any of this is read.                    |
| `PORT`                       | server | Port for `npm start`. Default `3000`.                                                                                                               |

## The `auth` module [#the-auth-module]

`VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` decide the gate: both set turns it on, neither is
open mode, and one without the other is `ProxyAuthMisconfigured` — the proxy refuses every request
rather than guessing which half you meant.

The other two are what the gate needs to be useful. Without `SUPABASE_SERVICE_ROLE_KEY` the server
cannot register a bot it just created; without `CHATFUEL_WORKSPACE_ID` it has no Chatfuel workspace
to create one in, and reports `ProxyWorkspaceMissing`.

| Name                        | Side              | What it is                                                                                                                                                                                        |
| --------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VITE_SUPABASE_URL`         | client and server | Project URL.                                                                                                                                                                                      |
| `VITE_SUPABASE_ANON_KEY`    | client and server | Publishable key.                                                                                                                                                                                  |
| `SUPABASE_SERVICE_ROLE_KEY` | server            | Secret key. Not optional under `auth`: it registers each bot the server creates, and it mounts the password-recovery route.                                                                       |
| `CHATFUEL_WORKSPACE_ID`     | server            | The one workspace every customer's bot is created in — the one whose plan pays for them all, so its bot limit is the ceiling for the whole deployment. Unrelated to `VITE_CHATFUEL_WORKSPACE_ID`. |

## The `publishing` module [#the-publishing-module]

Needed only for posts that go out unattended. Without them the module still composes and publishes
on the spot; it offers no schedule.

| Name                              | Side   | What it is                                                                                                                                                                                                                                    |
| --------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PUBLISHING_SECRET`               | server | What the app and its database use to prove a request came from the other. The database stores only its `sha256`.                                                                                                                              |
| `PUBLIC_URL`                      | server | Where this deployment answers from outside, e.g. `https://posts.example.com`. Without it the address is taken from the `Host` of whichever request turned scheduling on — fine on one domain, not behind a load balancer or on a preview URL. |
| `VERCEL_AUTOMATION_BYPASS_SECRET` | server | Set automatically on deployments whose production URL is protected, so the scheduling callback is not bounced at the edge before any code runs.                                                                                               |

## The `admin` module [#the-admin-module]

| Name             | Side   | What it is                                                                                                                                                                                            |
| ---------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ADMIN_PASSWORD` | server | The only thing that opens `/admin`, which reads and changes the whole account behind `CHATFUEL_TOKEN`. Unset means the admin routes are not mounted at all. Changing it signs every open session out. |

At least sixteen characters, or the panel refuses to run and says why. That floor is not fussiness:
the wrong-password counter lives in one process's memory, and a host that answers each request from
a fresh instance has nothing to share it in, so the length of this value is the defence that
survives.

`/admin` is never in the navigation rail. The URL is the whole way in.

## Serving from a sub-path [#serving-from-a-sub-path]

| Name             | Side   | What it is                    |
| ---------------- | ------ | ----------------------------- |
| `VITE_BASE_PATH` | client | Build-time base, e.g. `/app`. |
| `BASE_PATH`      | server | The same value at runtime.    |

Both or neither, and not on Vercel — see [Serving from a sub-path](/docs/deploy/sub-path).

## Behind a company proxy [#behind-a-company-proxy]

Node's built-in `fetch` ignores these unless the process was started with a flag nobody types, and
`ws` never reads them at all — so the proxy reads them itself, for HTTP and for the WebSocket
relay. The wizard's own outbound calls go through the same code.

| Name                         | Side   | What it is                                                                              |
| ---------------------------- | ------ | --------------------------------------------------------------------------------------- |
| `https_proxy`, `HTTPS_PROXY` | server | The proxy to send outbound requests through. First in the order that wins.              |
| `http_proxy`, `HTTP_PROXY`   | server | Next in that order.                                                                     |
| `all_proxy`, `ALL_PROXY`     | server | Last in that order.                                                                     |
| `no_proxy`, `NO_PROXY`       | server | A comma list of hosts, each matching itself and its subdomains, or `*` for all of them. |

Lowercase wins over uppercase, and an empty value means unset. Loopback is always exempt, whatever
`NO_PROXY` says — a dev server on this machine is not the proxy's business.

What has to be reachable: `panel.chatfuel.com` always, `registry.npmjs.org` to install anything,
`api.vercel.com` to deploy, `api.github.com` to push.

## Where the values go on a deployment [#where-the-values-go-on-a-deployment]

`npm run deploy` copies your `.env` into the Vercel project with `vercel env add --force`, for
production and preview. The file itself is never uploaded, so the project environment is the only
source there. Which values go up sensitive is on the [Vercel page](/docs/deploy/vercel).
