infra

Website migrated to Cloudflare Pages

Faster global edge delivery and simpler deploys.

By Howzer Team, Infra

Why we moved

We wanted faster global delivery and a simpler, deterministic build. Cloudflare Pages gives us edge caching out of the box, lightweight deploy previews, and a clean path from Next.js to static assets, ideal while we run self-hosted product infrastructure separately.

  • Global edge cache → lower TTFB for static pages
  • Deterministic builds via `@cloudflare/next-on-pages`
  • Simple `_headers` / `_redirects` for downloads & caching
  • Keeps app code minimal: no custom servers for the marketing site

What changed in the repo

  • Build script: `npm run pages:build` → runs `npx @cloudflare/next-on-pages`
  • Static output: `.vercel/output/static` published by Wrangler config
  • Next.js 13.x site (marketing), product infra stays self-hosted
  • CI logs show ignored build scripts are approved explicitly (when needed)
Build & delivery flow
CommitGitHubBuildnext-on-pagesOutput.vercel/output/staticEdgeCloudflare cacheBrowserimmutable assets

Caching & headers

  • Static assets: `/_next/static/*` → `Cache-Control: public, max-age=31536000, immutable`
  • Downloads (PDF): `_headers` with `Content-Disposition: attachment; filename="…"`, so clicks download instead of open
  • Page HTML: short max-age to allow quick content updates

Common pitfalls we fixed

  • Internal navigation uses `next/link`; file downloads use `<a href="/file.pdf" download>`
  • No TypeScript generics in `.jsx` files (e.g., `useState("enterprise")` statt `useState<...>`)
  • SVG focus ring removed on click (keeps keyboard accessibility)
  • Mobile navbar outside-click logic: checks trigger **and** panel refs

What’s next

  • Automated `_headers` generation for long-term caching & security
  • MDX/blocks authoring for articles (same renderer)
  • RSS/Atom feed (`/updates.xml`) and status badge integration