Local development
git clone https://github.com/Every-Man-A-Warrior/emaw-website.git
cd emaw-website
git checkout develop
npm install # not npm ci: package-lock.json is gitignored on purpose
cp .env.example .env.local
npm run dev # http://localhost:5173
Why npm install and no lockfile
The Vite/Tailwind 4 toolchain pulls platform-specific optional dependencies (lightningcss, sharp). A lockfile generated on Windows breaks the Linux build on Cloudflare, so package-lock.json is gitignored and CI uses npm install. Do not commit a lockfile.
Environment
Copy .env.example to .env.local and fill in the values from the team (names only here; see Configuration):
VITE_SANITY_PROJECT_ID,VITE_SANITY_DATASET,VITE_SANITY_API_VERSION,VITE_SANITY_STUDIO_URL: required; the app throws at startup without them.VITE_EMAW_API_BASE_URL=https://dev.emaw-app.comto use the shared dev backend, orhttp://localhost:8000for a host-run backend.VITE_STRIPE_PUBLISHABLE_KEY(pk_test_…) to enable checkout, paid registration and donations.VITE_GOOGLE_CLIENT_IDto show Google sign-in (yourlocalhost:5173origin must be authorised on the client).VITE_EMAW_APP_URLto enable the hand-off; point it athttp://localhost:5174with a local web app, or at the dev web app.
Scripts
| Script | Does |
|---|---|
npm run dev | Vite dev server on 5173 |
npm run dev:pages | Wrangler + Vite on 8788, for Pages-specific behaviour |
npm run build | tsc -b && vite build → dist/ |
npm run lint / npm run format | ESLint (flat config) / Prettier (no semicolons, single quotes, width 100) |
npm run deploy:develop | build with --mode development and deploy to Pages branch develop (what CI runs) |
npm run preview | serve dist/ |
Testing payments locally
With the dev backend and a pk_test_ key, the full store, event and donation flows work from localhost:5173 because the dev backend's CORS and COMMERCE_ALLOWED_ORIGINS allow it. Use the Stripe test cards. Orders land in the dev CRM and (sandbox) Deposco; nothing is charged.
Runbooks with test matrices:
Sanity draft mode
Append ?preview=1 to any URL to read drafts (needs VITE_SANITY_VIEWER_TOKEN); the mode persists in sessionStorage. In dev builds @sanity/visual-editing is enabled.
Conventions you will be held to
- Internal links go through
LocalizedLink/LocalizedNavLink(src/lib/i18n/Link.tsx), neverreact-router-dom'sLink, so/esis prefixed automatically. - Add an i18n namespace in both
src/lib/i18n/index.ts(imports andns) and both locale folders. - Use
getClient(preview)anduseSanityQuery, never the raw clients. src/types/sanity.types.tsis generated in the Studio repo; do not hand-edit.import typefor type-only imports (verbatimModuleSyntax),@/alias over deep relative paths.LayoutfetchessiteSettingsonce; do not re-fetch in pages.