Brick Heart: website construction
Current state of site
site/ ├── wrangler.jsonc (Cloudflare config) ├── languages.json (single list of languages) └── public/ (everything uploaded to the live site) ├── index.html (language picker) ├── 404.html (neutral fallback) ├── robots.txt ├── sitemap.xml (generated) ├── _headers (security headers) ├── css/base.css (shared styles) ├── js/picker.js ├── en/ index.html, 404.html └── zh/ index.html, 404.html scripts/build-sitemap.mjs
Key decisions
- Language tags: Full BCP 47 tags (en-GB, zh-Hans, sr-Cyrl-RS) go in hreflang and lang, while folders use just the first part (/en/, /zh/). Each language label is written in its own language, and ar gets dir="rtl".
- Accessibility and direction: The CSS uses logical properties, so it works for both LTR and RTL. It also has visible focus rings, 44px targets, dark mode, reduced motion, forced-colors support, a skip link and proper landmarks.
- Picker behaviour: First-time visitors see the picker. A chosen language is saved in localStorage and returning visitors are sent to /en/ and so on. The "Change language" link goes to /?change, which clears the saved choice.
- Security headers: A strict Content Security Policy means no inline <style>, <script>, style="" or onclick="". Styles go in .css files and scripts in .js files.
- 404 pages: One per language folder plus a neutral root one, rather than hardcoding every language in one page. Cloudflare's 404-page setting serves the nearest one.
- hreflang lives in the sitemap only. npm run build regenerates sitemap.xml from languages.json, and Cloudflare runs it on every deploy.
Next steps
- Generate the picker from languages.json. It's the last repetitive step, so do it when adding a third language such as de-DE.
- Consider a template-based build for the language pages once there are more than a handful.
- Start dev/ as a second Worker with its own wrangler.jsonc, then app/.
- Move shared CSS into a top-level shared/ folder, copied into each project at build time, once dev/ exists. They are separate origins and the app must work offline.
- Optional: Google Search Console, and a redirect from brickheart.org to www.