Deploying TanStack Start to Cloudflare Workers
Vite plugin, wrangler deploy, DNS, cache headers, and Web Analytics — without a heavy backend.
This site is a Cloudflare Worker from Vite + TanStack Start. Deploy with pnpm build then wrangler deploy (or pnpm deploy). Small setup; worth recording once.
Vite + Cloudflare plugin
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import viteReact from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
cloudflare({ viteEnvironment: { name: 'ssr' } }),
tailwindcss(),
tanstackStart(),
viteReact(),
],
})
// wrangler.jsonc
{
"name": "forleoliang",
"compatibility_date": "2025-09-02",
"compatibility_flags": ["nodejs_compat"],
"main": "@tanstack/react-start/server-entry",
}
Build output under dist/: Worker entry + client assets. SSR HTML goes through the Worker; hashed /assets/* can cache forever.
DNS and deploy
Domain on Cloudflare DNS. wrangler.jsonc names the Worker. Git push to main can build via Cloudflare if you prefer not to run Wrangler locally.
- Production origin in one place (
src/lib/site.ts) for RSS, OG, absolute links. - Consistent trailing slashes so links do not bounce.
- Long-cache
/assets/*and fonts; short-lived HTML (public/_headers).
Analytics without cookies
Cloudflare Web Analytics is enough: aggregate views and referrers, no marketing tag manager. Enable in the dashboard so the beacon injects at the edge — no token in source, no double script.
Keep it lean
Workers free tier covers a profile site. Domain registration is the only bill. No D1 / R2 / KV until traffic or content needs them. Forms or small APIs → one createServerFn or Worker route, not a second framework.
Product apps (ToolifyNav, StartOCR, FreeTempMail) do use D1 / R2 / KV / Queues. This site stays lean on purpose.
Checklist
- Cloudflare Vite plugin configured;
pnpm buildsucceeds locally. wrangler deploy(or CI) publishes without broken asset paths.robots.txt, RSS, and canonicals point at production.- Security headers via
public/_headers. - Analytics enabled once — not both in HTML and the dashboard.
Patterns live in the public profile repo linked from this site.