# TanStack Start + Cloudflare Workers Webapp Structure

{{PROJECT_NAME}}/
├── apps/
│   └── web/
│       ├── src/
│       │   ├── routes/
│       │   │   ├── __root.tsx          # Root shell with <HeadContent /> and <Scripts />
│       │   │   ├── index.tsx           # / SSR or prerender-capable public landing
│       │   │   └── app.tsx             # /app client-only workspace route with ssr: false
│       │   ├── components/
│       │   │   ├── landing/            # Public landing sections, meta-friendly content
│       │   │   └── workspace/          # Authenticated/browser-heavy app components
│       │   ├── lib/
│       │   │   ├── api.ts              # VITE_API_BASE_URL / VITE_AGENT_API_URL clients
│       │   │   └── seo.ts              # title, meta, OG, canonical helpers
│       │   ├── router.tsx              # createRouter / route tree wiring
│       │   ├── routeTree.gen.ts        # generated by TanStack Router/Start tooling
│       │   └── styles.css
│       ├── public/
│       ├── vite.config.ts              # cloudflare(), tanstackStart(), react()
│       ├── wrangler.jsonc              # Worker name, main/assets, compatibility_date
│       ├── package.json                # build, dev, preview, deploy, cf-typegen
│       └── tsconfig.json
├── apps/
│   ├── api/                            # optional Hono Worker only when API owns data authority
│   ├── agent/                          # optional Agent Worker only when agent runtime is separate
│   └── mcp/                            # optional MCP Worker only when external tool access exists
├── packages/
│   └── contracts/                      # shared Zod/Valibot route, API, agent, and UI contracts
├── deploy/
│   ├── env/.env.example                # VITE_API_BASE_URL, VITE_AGENT_API_URL, public site URL
│   └── runbooks/                       # domain cutover, Worker routes, rollback notes
└── docs/
    └── architecture/                   # web SSR/client boundary and backend runtime ownership

Route boundary:
- `/`: public landing route. It must return crawler-visible HTML, title/meta,
  Open Graph tags, and canonical URL from the Worker SSR/prerender path.
- `/app`: workspace route. Set route-level `ssr: false` or an equivalent
  client-only boundary; do not SSR tenant workspace data.
- Browser-only or WebGL components should be `React.lazy`/client-only imports
  inside `/app`, not top-level imports in server-rendered route modules.

Deployment boundary:
- Deploy `apps/web` as one Cloudflare Worker with Worker assets and
  `wrangler deploy`; do not scaffold a second default frontend component.
- Keep backend Workers separate only when they own API, Agent, MCP, queue, or
  storage authority.
- Keep any legacy `apps/marketing` Pages surface as explicit rollback material,
  not as the default scaffold target.
