The Auditmos landing page — Astro on Cloudflare Workers.
Static-first, SEO-friendly site replacing the previous auditmos.com. Built as a credibility/trust signal for prospects who arrive via referrals, LinkedIn, conferences, or partner introductions. Every URL also serves text/markdown at <url>.md (indexed via /llms.txt) so AI agents can ingest the entire site without scraping HTML.
- PRD:
docs/prd-website-rebuild.md(issue #1) - Plan:
plans/website-rebuild.md— 7 phased tracer-bullet issues (#2–#8) - Brand: accent
#04d9ff, logos vendored fromauditmos/branding - Entity: Auditmos OÜ · Reg 17025406 · VAT EE102758111 · Tallinn, Estonia
Every page is prerendered HTML served from Cloudflare's edge. Exactly one request-time route — /api/contact — runs on the Worker (Zod → Turnstile verify → Resend notify + confirm, atomic semantics).
- Content: Astro Content Collections + Zod for projects. Authoring = drop MD in
src/content/projects/, commit, push. - MD-mirror: every URL has a
.mdtwin via*.md.tsendpoints;/llms.txtis the index. A single page-enumerator is the source of truth — adding a route extends both surfaces. - OSS page: auto-aggregated from
github.com/auditmosat build time with cached/empty fallback so GitHub outages never break a deploy. - Confidentiality: project
clientfield is either{ name, url? }(public) or{ sector }(anonymised NDA work). Same pipeline serves both. - Analytics: Cloudflare Web Analytics only — no cookies, no consent banner.
See docs/prd-website-rebuild.md for the full specification.
| Layer | Technology |
|---|---|
| Framework | Astro 6 (mostly prerender = true) |
| Adapter | @astrojs/cloudflare |
| Runtime | Cloudflare Workers (nodejs_compat) |
| Styling | Tailwind CSS v4 (@tailwindcss/vite) |
| Content | Astro Content Collections + Zod |
| Resend (transactional) | |
| Anti-spam | Cloudflare Turnstile |
| Analytics | Cloudflare Web Analytics |
| Language | TypeScript (strict, @/* → src/*) |
| Linter | Biome 2 |
| Testing | Vitest |
| Dead-code | knip |
| Release | semantic-release |
| Package manager | pnpm 10 |
pnpm install
pnpm cf-typegen
pnpm dev # http://localhost:3000pnpm new-project "Acme audit" # scaffolds src/content/projects/acme-audit.mdEdit the frontmatter + body, commit, push to main. GitHub Actions deploys to staging automatically. Production cutover is a Cloudflare custom-domain swap.
| Script | Purpose |
|---|---|
pnpm dev |
Dev server on port 3000 |
pnpm build |
Production build to ./dist |
pnpm preview |
Preview the production build locally |
pnpm deploy |
Build + wrangler deploy |
pnpm cf-typegen |
Regenerate Env types from wrangler.jsonc |
pnpm new-project "<title>" |
Scaffold a new project MD with frontmatter |
pnpm test / pnpm test:watch / pnpm test:coverage |
Vitest |
pnpm types |
astro check + tsc --noEmit |
pnpm lint / pnpm lint:fix |
Biome |
pnpm knip |
Unused files / deps / exports |
pnpm deps / pnpm deps:update |
Dependency updates via taze |
pnpm release |
semantic-release (CI only) |
src/
├── pages/ # File-based routes (mostly prerender = true)
│ ├── index.astro # Home
│ ├── software-development.astro
│ ├── r-and-d.astro
│ ├── security-audits.astro
│ ├── projects/ # /projects + /projects/[slug]
│ ├── open-source.astro
│ ├── about.astro
│ ├── contact.astro
│ ├── privacy.astro
│ ├── llms.txt.ts # AI agent index
│ └── api/contact.ts # Worker route (only non-prerendered route)
├── content/
│ └── projects/ # Markdown source for projects
├── layouts/Layout.astro # Shared HTML shell + footer
├── components/ # Reusable Astro components
├── assets/logos/ # Vendored from github.com/auditmos/branding
└── styles/globals.css # Tailwind v4 entry + @theme tokens
Path alias @/* resolves to src/*.
Three Wrangler env blocks (dev, staging, production), each with its own Worker name. Deploy a specific env with wrangler deploy --env <name>.
Copy .dev.vars.example, .dev.vars.staging.example, or .dev.vars.production.example
to the matching ignored .dev.vars / .dev.vars.staging / .dev.vars.production file
and fill these values. This matches the wrangler convention — .dev.vars.<env> is loaded
ahead of .dev.vars when CLOUDFLARE_ENV=<env> is set.
| Name | Purpose |
|---|---|
TURNSTILE_SITE_KEY |
Public Cloudflare Turnstile widget key for /contact |
RESEND_API_KEY |
Resend transactional email |
TURNSTILE_SECRET_KEY |
Cloudflare Turnstile siteverify |
CONTACT_TO_EMAIL |
Form recipient inbox (contact@auditmos.com in production) |
GITHUB_TOKEN (optional) |
Raises OSS aggregator rate limit at build time |
Resend sends from noreply@auditmos.com — DKIM + SPF on auditmos.com DNS must be verified in Resend before launch.
import { env } from "cloudflare:workers";
const apiKey = env.RESEND_API_KEY; // typed via worker-configuration.d.tsAstro.locals.runtime is removed in Astro v6 + @astrojs/cloudflare v13 — import { env } from "cloudflare:workers" is the only supported path. Run pnpm cf-typegen after editing wrangler.jsonc bindings.
DNS is on Cloudflare. Prefer custom_domain: true over routes with zone_name — see .claude/rules/cloudflare-deployment.md.
CLAUDE.md— project-level agent guide..claude/rules/— topic rules that activate automatically based on the files being edited..claude/agents/—dd-w(design-doc writer),dd-i(design-doc implementer),mvp-e(MVP enforcer)./docs— single source of truth for business requirements./plans— phased implementation plans derived from docs.
- Astro — content-first framework with islands architecture
- @astrojs/cloudflare — Cloudflare Workers adapter
- Tailwind CSS v4 — utility-first CSS, configured via CSS
- Cloudflare Workers — edge computing platform
- Resend — transactional email
- Cloudflare Turnstile — privacy-respecting anti-spam
- Biome — fast formatter and linter
Open source under the ISC License.