Skip to content
CafeJS Docs

Environment variables

Running locally needs none. To go live, the variables below are read at build time; changing any of them needs a new build.

The variables

VariableWhenWhat for
TINA_CLIENT_IDWay 1The TinaCloud project’s Client ID
TINA_TOKENWay 1The TinaCloud project’s read-only token
GITHUB_BRANCHWay 1, when content isn’t on mainThe branch TinaCloud reads and writes
SITE_URLGoing liveThe site’s root address. Without it there is no canonical, no sitemap.xml and no structured data for Google
PUBLIC_FORM_ENDPOINTSites with a contact or booking formWhere the form’s answers go. Empty: the form only shows the sample-site notice and sends nothing
TINA_PUBLIC_ADMIN_READONLY, TINA_PUBLIC_CONTENT_API_URLThe preview adminpnpm build:review sets both

The sample file

The template ships a .env.example:

.env.example
# TinaCloud project, only needed for `pnpm build` and the deployed admin
TINA_CLIENT_ID=
TINA_TOKEN=

# Public preview admin (`pnpm build:review` sets both): no sign-in, nothing saved, and the
# server answers the admin's GraphQL itself at /api/tina/gql (see DEPLOY.md).
TINA_PUBLIC_ADMIN_READONLY=
TINA_PUBLIC_CONTENT_API_URL=

# The site's address, read at build time (https://example.com). Set it for go-live: canonical,
# og:url, the JSON-LD graph and sitemap.xml exist only in a build that has it. Unset, the build
# warns once and leaves them out.
# SITE_URL=

# Where the contactForm section posts its answers (JSON), read at build time. Empty: the
# form only shows the sample-site notice and sends nothing. https URL, local http URL or /path.
PUBLIC_FORM_ENDPOINT=

Note

Environment variables are read at build time. Any change needs a new build.

SITE_URL

With SITE_URL, pages get a canonical and og:url, Open Graph images and hreflang become full addresses, every indexed page gets a structured-data block, and sitemap.xml is written. Without it the build prints a warning and leaves those out; robots.txt is still there.

PUBLIC_FORM_ENDPOINT

The form sends POST JSON { locale, page, form, fields } to this address; a 2xx answer means success, and after 15 seconds it reports an error. It accepts https://…, a local http://localhost… address, or a same-site path /….

  • fields are named by each row’s Name sent to the endpoint field, the same in vi and en.
  • form is the section’s anchor, so the receiver tells forms apart by form together with locale.
  • A receiver on another domain must allow CORS (POST, header Content-Type: application/json) from the site’s domain.

Danger

This address is public in the HTML of every page with a form. Never put a secret key in the URL, and limit how often the receiver accepts a submission.