Render the widget on the contact, event registration and both application forms, and verify the token with Siteverify in each action before anything is written to the CMS. Verification fails closed. The check is off unless both TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY are set. Allow challenges.cloudflare.com in script-src and frame-src. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
60 lines
2.8 KiB
Bash
60 lines
2.8 KiB
Bash
# ---------------------------------------------------------------------------
|
|
# SHARP-ER web (React Router 8) - environment template
|
|
#
|
|
# Copy to .env and fill in real values: cp .env.example .env
|
|
# Never commit .env.
|
|
#
|
|
# `pnpm --filter web start` loads THIS file (apps/web/.env), the same way the
|
|
# CMS loads apps/cms/.env. It is per-application on purpose: PORT and HOST mean
|
|
# something different to each server, and a single shared value would move
|
|
# Strapi onto the website's port. The repository-root .env is docker compose's
|
|
# file and is not read here.
|
|
#
|
|
# A real environment variable always wins over this file, so a systemd unit,
|
|
# a container or `PORT=9090 pnpm --filter web start` overrides any line below.
|
|
#
|
|
# `pnpm dev:web` does NOT read this file - the dev server is Vite on 5173, and
|
|
# it only exposes variables prefixed VITE_, by inlining them into the CLIENT
|
|
# bundle. Never use that prefix here: STRAPI_TOKEN below is a server secret.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# --- Server ----------------------------------------------------------------
|
|
|
|
# Port react-router-serve binds. Leave it unset and the server takes the first
|
|
# FREE port from 3000 upwards - 3001, 3002, ... once 3000 is busy - which a
|
|
# reverse proxy cannot be pointed at. `pnpm dev:web` ignores this and uses 5173.
|
|
PORT=3000
|
|
|
|
# Interface to bind. Unset means every interface. Set it to 127.0.0.1 when a
|
|
# reverse proxy on the same host should be the only way in.
|
|
# HOST=127.0.0.1
|
|
|
|
# --- Content ---------------------------------------------------------------
|
|
|
|
# Public origin of the site. Canonical URLs, hreflang alternates and JSON-LD
|
|
# are built from it, so it must match how visitors actually reach the site -
|
|
# https://sharper.ly in production, never the internal http://127.0.0.1:3000.
|
|
# Leave it unset in local development and the request's own host is used.
|
|
SITE_URL=http://localhost:3000
|
|
|
|
# Where the server-side loaders fetch content from. This origin is also
|
|
# prefixed onto uploaded media URLs, which the browser has to resolve too -
|
|
# see "Images from the CMS" in README.md.
|
|
STRAPI_URL=http://localhost:1337
|
|
|
|
# Optional Strapi API token. Only needed to read draft or otherwise protected
|
|
# content; published content is public. Settings -> API Tokens in the admin.
|
|
STRAPI_TOKEN=
|
|
|
|
# --- Bot protection --------------------------------------------------------
|
|
|
|
# Cloudflare Turnstile on the public forms (contact, event registration and
|
|
# both application forms). Both keys or neither: with either one empty, no
|
|
# widget renders and submissions are not checked. The site key is public and
|
|
# reaches the browser; the secret key never does.
|
|
# Cloudflare dashboard -> Turnstile -> your widget. For local testing,
|
|
# Cloudflare's always-pass pair is 1x00000000000000000000AA (site) and
|
|
# 1x0000000000000000000000000000000AA (secret).
|
|
TURNSTILE_SITE_KEY=
|
|
TURNSTILE_SECRET_KEY=
|