vite-flare-starter
用 vite-flare-starter 模板建立並部署全端 Cloudflare app
中文翻譯
--- name: vite-flare-starter description: "從 vite-flare-starter 模板建出全端 Cloudflare app 的腳手架:React 19 + Hono + D1+Drizzle + better-auth + Tailwind v4+shadcn/ui + TanStack Query + R2 + Workers AI。執行 setup.sh 來 clone、設定並部署。只要使用者想要一個功能齊全的 Cloudflare 全端 app、vite-flare-starter 腳手架,或一個驗證 + 資料庫 + Workers AI 都準備好的 React + Cloudflare app,就用這個 skill。" compatibility: claude-code-only --- # Vite Flare Starter 把功能齊全的 Cloudflare starter clone 下來,設定成獨立的專案。產出一個完整換上自己品牌、可以部署的全端 app。 ## 技術堆疊 | 層 | 技術 | 版本 | |-------|-----------|---------| | 前端 | React、Vite、Tailwind CSS、shadcn/ui | 19、6.x、v4、latest | | 後端 | Hono(跑在 Cloudflare Workers 上) | 4.x | | 資料庫 | D1(邊緣的 SQLite)+ Drizzle ORM | 0.38+ | | 驗證 | better-auth(Google OAuth + email/password) | latest | | 儲存 | R2(相容 S3 的物件儲存) | — | | AI | Workers AI binding | — | | 資料抓取 | TanStack Query | v5 | ### Cloudflare Binding | Binding | 類型 | 用途 | |---------|------|---------| | `DB` | D1 Database | 主要的應用程式資料庫 | | `AVATARS` | R2 Bucket | 使用者頭像儲存 | | `FILES` | R2 Bucket | 一般檔案上傳 | | `AI` | Workers AI | AI 模型推論 | ### 專案結構 ``` src/ ├── client/ # React frontend │ ├── components/ # UI components │ ├── hooks/ # Custom hooks + TanStack Query │ ├── pages/ # Route pages │ ├── lib/ # Utilities (auth client, etc.) │ └── main.tsx # App entry point ├── server/ # Hono backend │ ├── index.ts # Worker entry point │ ├── routes/ # API routes │ ├── middleware/ # Auth, CORS, etc. │ └── db/ # Drizzle schema + queries └── shared/ # Shared types between client/server ``` ### 重要指令 | 指令 | 用途 | |---------|---------| | `pnpm dev` | 啟動本機開發 server | | `pnpm build` | 正式環境 build | | `pnpm deploy` | 部署到 Cloudflare | | `pnpm db:migrate:local` | 在本機套用 migration | | `pnpm db:migrate:remote` | 把 migration 套用到正式環境 | | `pnpm db:generate` | 依 schema 的變更產生 migration | ## 工作流程 ### 步驟 1:收集專案資訊 詢問: | 必填 | 選填 | |----------|----------| | 專案名稱(kebab-case) | 管理員 email | | 描述(一句話) | Google OAuth 憑證 | | Cloudflare 帳號 | 自訂網域 | ### 步驟 2:Clone 並設定 #### 2a. Clone 並清理 ```bash git clone https://github.com/jezweb/vite-flare-starter.git PROJECT_DIR --depth 1 cd PROJECT_DIR rm -rf .git git init ``` #### 2b. 要尋找取代的目標 把這些位置的 `vite-flare-starter` 換成專案名稱: | 檔案 | 目標 | 取代成 | |------|--------|-------------| | `wrangler.jsonc` | `"vite-flare-starter"`(worker 名稱) | `"PROJECT_NAME"` | | `wrangler.jsonc` | `vite-flare-starter-db` | `PROJECT_NAME-db` | | `wrangler.jsonc` | `vite-flare-starter-avatars` | `PROJECT_NAME-avatars` | | `wrangler.jsonc` | `vite-flare-starter-files` | `PROJECT_NAME-files` | | `package.json` | `"name": "vite-flare-starter"` | `"name": "PROJECT_NAME"` | | `package.json` | `vite-flare-starter-db` | `PROJECT_NAME-db` | | `index.html` | `<title>` 的內容 | App 顯示名稱(Title Case) | 同樣在 `wrangler.jsonc` 裡: - **移除**寫死的 `account_id` 那一行(讓 wrangler 提示或改用環境變數) - **把** `database_id` 的值**換成** `REPLACE_WITH_YOUR_DATABASE_ID` 把 `package.json` 的 version 重設成 `"0.1.0"`。 取代時用 Edit 工具(比 sed 更好,可避免 macOS/GNU 的差異)。 #### 2c. 產生驗證用的 secret ```bash BETTER_AUTH_SECRET=$(openssl rand -hex 32 2>/dev/null || python3 -c "import secrets; print(secrets.token_hex(32))") ``` #### 2d. 建立 .dev.vars 轉換 kebab-case 的專案名稱:`my-cool-app` 變成顯示名稱 `My Cool App`、ID `my_cool_app`。 ``` # Local Development Environment Variables # DO NOT COMMIT THIS FILE TO GIT # Authentication (better-auth) BETTER_AUTH_SECRET=<generated> BETTER_AUTH_URL=http://localhost:5173 # Google OAuth (optional) GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= # Email Auth Control (disabled by default) # ENABLE_EMAIL_LOGIN=true # ENABLE_EMAIL_SIGNUP=true # Application Configuration APP_NAME=<Display Name> VITE_APP_NAME=<Display Name> VITE_APP_ID=<app_id> VITE_TOKEN_PREFIX=<app_id>_ VITE_GITHUB_URL= VITE_FOOTER_TEXT= NODE_ENV=development ``` #### 2e. 建立 Cloudflare 資源(選用) ```bash npx wrangler d1 create PROJECT_NAME-db # Extract database_id from output, update wrangler.jsonc npx wrangler r2 bucket create PROJECT_NAME-avatars npx wrangler r2 bucket create PROJECT_NAME-files ``` #### 2f. 安裝並 migrate ```bash pnpm install pnpm run db:migrate:local ``` #### 2g. 初始 commit ```bash git add -A git commit -m "Initial commit from vite-flare-starter" ``` ### 步驟 3:手動設定 1. **Google OAuth**(如果要用):到 Google Cloud Console 建立 OAuth 2.0 Client ID,加入 redirect URI `http://localhost:5173/api/auth/callback/google`,把 Client ID 和 Secret 複製到 `.dev.vars` 2. **Favicon**:替換 `public/favicon.svg` 3. **CLAUDE.md**:更新專案描述,移除對 vite-flare-starter 的參照 4. **index.html**:更新 `<title>` 和 meta description ### 步驟 4:本機驗證 ```bash pnpm dev ``` 檢查:http://localhost:5173 能載入、顯示的是**你的** app 名稱、註冊/登入能運作(如果有設定 OAuth)。 ### 步驟 5:部署到正式環境 ```bash # Set production secrets openssl rand -base64 32 | npx wrangler secret put BETTER_AUTH_SECRET echo "https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put BETTER_AUTH_URL echo "http://localhost:5173,https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put TRUSTED_ORIGINS # If using Google OAuth echo "your-client-id" | npx wrangler secret put GOOGLE_CLIENT_ID echo "your-client-secret" | npx wrangler secret put GOOGLE_CLIENT_SECRET # Migrate remote database pnpm run db:migrate:remote # Build and deploy pnpm run build && pnpm run deploy ``` **重要**:第一次部署之後,把 BETTER_AUTH_URL 更新成你實際的 Worker URL。把正式環境的網址加到 Google OAuth 的 redirect URI。 ## 安全指紋 把這些全部改掉,讓攻擊者無法辨識你的網站用的是這個 starter: | 位置 | 預設值 | 怎麼改 | |----------|---------------|---------------| | 頁面標題 | "Vite Flare Starter" | `index.html` | | UI 裡的 app 名稱 | "Vite Flare Starter" | `VITE_APP_NAME` 環境變數 | | localStorage key | `vite-flare-starter-theme` | `VITE_APP_ID` 環境變數 | | API token | `vfs_` 前綴 | `VITE_TOKEN_PREFIX` 環境變數 | | GitHub 連結 | starter repo | `VITE_GITHUB_URL`(設成空的就會隱藏) | | Worker 名稱 | `vite-flare-starter` | `wrangler.jsonc` | | 資料庫名稱 | `vite-flare-starter-db` | `wrangler.jsonc` | | R2 bucket | `vite-flare-starter-*` | `wrangler.jsonc` | ## 環境變數 ### 品牌(VITE_ 前綴 = 前端可用) | 變數 | 用途 | 範例 | |----------|---------|---------| | `VITE_APP_NAME` | UI 裡的顯示名稱 | "My Cool App" | | `VITE_APP_ID` | localStorage 前綴、Sentry | "mycoolapp" | | `VITE_TOKEN_PREFIX` | API token 前綴 | "mca_" | | `VITE_GITHUB_URL` | GitHub 連結(空的 = 隱藏) | "" | | `VITE_FOOTER_TEXT` | 頁尾版權文字 | "2026 My Company" | | `APP_NAME` | Server 端的 app 名稱 | "My Cool App" | ### 驗證 | 變數 | 用途 | 備註 | |----------|---------|-------| | `BETTER_AUTH_SECRET` | Session 加密 | `openssl rand -hex 32` | | `BETTER_AUTH_URL` | 驗證的 base URL | 必須跟實際網址完全一致 | | `TRUSTED_ORIGINS` | 允許的 origin | 以逗號分隔,包含 localhost + 正式環境 | | `GOOGLE_CLIENT_ID` | Google OAuth | 從 Google Cloud Console 取得 | | `GOOGLE_CLIENT_SECRET` | Google OAuth | 從 Google Cloud Console 取得 | | `ENABLE_EMAIL_LOGIN` | 啟用 email/password | "true" 才會啟用 | | `ENABLE_EMAIL_SIGNUP` | 啟用 email 註冊 | 需要 ENABLE_EMAIL_LOGIN | ### Email(選用) | 變數 | 用途 | 備註 | |----------|---------|-------| | `EMAIL_FROM` | 寄件人地址 | 用於驗證/密碼重設 | | `EMAIL_API_KEY` | Email 服務的 API key | 建議用 Resend | ## 常見客製化 ### 新增資料表 1. 在 `src/server/db/schema.ts` 加上 schema 2. 產生 migration:`pnpm db:generate` 3. 在本機套用:`pnpm db:migrate:local` 4. 套用到正式環境:`pnpm db:migrate:remote` ### 新增 API Route 1. 在 `src/server/routes/` 建立 route 檔案 2. 在 `src/server/index.ts` 註冊 3. 在 `src/client/hooks/` 加上 TanStack Query hook ### 更換驗證提供者 編輯 `src/server/auth.ts`:把 provider 加到 `socialProviders`,把憑證加到 `.dev.vars` 和正式環境的 secret,並更新前端的登入按鈕。 ### Feature Flag 透過環境變數控制功能:`VITE_FEATURE_STYLE_GUIDE=true`、`VITE_FEATURE_COMPONENTS=true`。自己的 flag 加在 `src/client/lib/features.ts`。 ## 疑難排解 | 症狀 | 原因 | 解法 | |---------|-------|-----| | 驗證後無聲地導回首頁 | 缺少 TRUSTED_ORIGINS | 把所有合法的網址設進 TRUSTED_ORIGINS | | 部署時出現 "Not authorized" | account_id 錯誤 | 從 wrangler.jsonc 移除 account_id,或設成你自己的 | | 資料庫 500 錯誤 | 缺少 migration | 執行 `pnpm db:migrate:local` 和 `pnpm db:migrate:remote` | | localStorage 顯示 "vite-flare-starter" | 缺少 VITE_APP_ID | 在 .dev.vars 設定 `VITE_APP_ID=yourapp` | | 只有正式環境驗證失敗 | BETTER_AUTH_URL 不一致 | 必須跟實際的 Worker URL 完全一致(https,結尾不要有斜線) | | Google 登入時出現 "redirect_uri_mismatch" | 缺少 OAuth redirect URI | 把正式環境網址加到 Google Cloud Console 的 OAuth redirect URI | | 改了 secret 卻沒有效果 | 沒有重新部署 | `wrangler secret put` **不會**重新部署。之後要執行 `pnpm deploy` | ## 正式環境部署檢查清單 - [ ] 已設定 `BETTER_AUTH_SECRET`(要跟開發環境不同!) - [ ] `BETTER_AUTH_URL` 與實際的 Worker URL 一致 - [ ] `TRUSTED_ORIGINS` 包含所有合法的網址 - [ ] Google OAuth 的 redirect URI 包含正式環境網址 - [ ] 遠端資料庫已 migrate(`pnpm db:migrate:remote`) - [ ] 設定檔裡沒有任何 `vite-flare-starter` 的參照 - [ ] Favicon 已替換 - [ ] CLAUDE.md 已更新 - [ ] `.dev.vars` 沒有被 commit(檢查 `.gitignore`)
英文原文
--- name: vite-flare-starter description: "Scaffold a full-stack Cloudflare app from the vite-flare-starter template — React 19 + Hono + D1+Drizzle + better-auth + Tailwind v4+shadcn/ui + TanStack Query + R2 + Workers AI. Run setup.sh to clone, configure, and deploy. Use whenever the user wants a batteries-included Cloudflare full-stack app, vite-flare-starter scaffold, or a React + Cloudflare app with auth + database + Workers AI ready to go." compatibility: claude-code-only --- # Vite Flare Starter Clone and configure the batteries-included Cloudflare starter into a standalone project. Produces a fully rebranded, deployable full-stack app. ## Stack | Layer | Technology | Version | |-------|-----------|---------| | Frontend | React, Vite, Tailwind CSS, shadcn/ui | 19, 6.x, v4, latest | | Backend | Hono (on Cloudflare Workers) | 4.x | | Database | D1 (SQLite at edge) + Drizzle ORM | 0.38+ | | Auth | better-auth (Google OAuth + email/password) | latest | | Storage | R2 (S3-compatible object storage) | — | | AI | Workers AI binding | — | | Data Fetching | TanStack Query | v5 | ### Cloudflare Bindings | Binding | Type | Purpose | |---------|------|---------| | `DB` | D1 Database | Primary application database | | `AVATARS` | R2 Bucket | User avatar storage | | `FILES` | R2 Bucket | General file uploads | | `AI` | Workers AI | AI model inference | ### Project Structure ``` src/ ├── client/ # React frontend │ ├── components/ # UI components │ ├── hooks/ # Custom hooks + TanStack Query │ ├── pages/ # Route pages │ ├── lib/ # Utilities (auth client, etc.) │ └── main.tsx # App entry point ├── server/ # Hono backend │ ├── index.ts # Worker entry point │ ├── routes/ # API routes │ ├── middleware/ # Auth, CORS, etc. │ └── db/ # Drizzle schema + queries └── shared/ # Shared types between client/server ``` ### Key Commands | Command | Purpose | |---------|---------| | `pnpm dev` | Start local dev server | | `pnpm build` | Production build | | `pnpm deploy` | Deploy to Cloudflare | | `pnpm db:migrate:local` | Apply migrations locally | | `pnpm db:migrate:remote` | Apply migrations to production | | `pnpm db:generate` | Generate migration from schema changes | ## Workflow ### Step 1: Gather Project Info Ask for: | Required | Optional | |----------|----------| | Project name (kebab-case) | Admin email | | Description (1 sentence) | Google OAuth credentials | | Cloudflare account | Custom domain | ### Step 2: Clone and Configure #### 2a. Clone and clean ```bash git clone https://github.com/jezweb/vite-flare-starter.git PROJECT_DIR --depth 1 cd PROJECT_DIR rm -rf .git git init ``` #### 2b. Find-replace targets Replace `vite-flare-starter` with the project name in these locations: | File | Target | Replace with | |------|--------|-------------| | `wrangler.jsonc` | `"vite-flare-starter"` (worker name) | `"PROJECT_NAME"` | | `wrangler.jsonc` | `vite-flare-starter-db` | `PROJECT_NAME-db` | | `wrangler.jsonc` | `vite-flare-starter-avatars` | `PROJECT_NAME-avatars` | | `wrangler.jsonc` | `vite-flare-starter-files` | `PROJECT_NAME-files` | | `package.json` | `"name": "vite-flare-starter"` | `"name": "PROJECT_NAME"` | | `package.json` | `vite-flare-starter-db` | `PROJECT_NAME-db` | | `index.html` | `<title>` content | App display name (Title Case) | Also in `wrangler.jsonc`: - **Remove** hardcoded `account_id` line (let wrangler prompt or use env var) - **Replace** `database_id` value with `REPLACE_WITH_YOUR_DATABASE_ID` Reset `package.json` version to `"0.1.0"`. Use the Edit tool for replacements (preferred over sed to avoid macOS/GNU differences). #### 2c. Generate auth secret ```bash BETTER_AUTH_SECRET=$(openssl rand -hex 32 2>/dev/null || python3 -c "import secrets; print(secrets.token_hex(32))") ``` #### 2d. Create .dev.vars Convert kebab-case project name: `my-cool-app` becomes Display `My Cool App`, ID `my_cool_app`. ``` # Local Development Environment Variables # DO NOT COMMIT THIS FILE TO GIT # Authentication (better-auth) BETTER_AUTH_SECRET=<generated> BETTER_AUTH_URL=http://localhost:5173 # Google OAuth (optional) GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= # Email Auth Control (disabled by default) # ENABLE_EMAIL_LOGIN=true # ENABLE_EMAIL_SIGNUP=true # Application Configuration APP_NAME=<Display Name> VITE_APP_NAME=<Display Name> VITE_APP_ID=<app_id> VITE_TOKEN_PREFIX=<app_id>_ VITE_GITHUB_URL= VITE_FOOTER_TEXT= NODE_ENV=development ``` #### 2e. Create Cloudflare resources (optional) ```bash npx wrangler d1 create PROJECT_NAME-db # Extract database_id from output, update wrangler.jsonc npx wrangler r2 bucket create PROJECT_NAME-avatars npx wrangler r2 bucket create PROJECT_NAME-files ``` #### 2f. Install and migrate ```bash pnpm install pnpm run db:migrate:local ``` #### 2g. Initial commit ```bash git add -A git commit -m "Initial commit from vite-flare-starter" ``` ### Step 3: Manual Configuration 1. **Google OAuth** (if using): Go to Google Cloud Console, create OAuth 2.0 Client ID, add redirect URI `http://localhost:5173/api/auth/callback/google`, copy Client ID and Secret to `.dev.vars` 2. **Favicon**: Replace `public/favicon.svg` 3. **CLAUDE.md**: Update project description, remove vite-flare-starter references 4. **index.html**: Update `<title>` and meta description ### Step 4: Verify Locally ```bash pnpm dev ``` Check: http://localhost:5173 loads, shows YOUR app name, sign-up/sign-in works (if OAuth configured). ### Step 5: Deploy to Production ```bash # Set production secrets openssl rand -base64 32 | npx wrangler secret put BETTER_AUTH_SECRET echo "https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put BETTER_AUTH_URL echo "http://localhost:5173,https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put TRUSTED_ORIGINS # If using Google OAuth echo "your-client-id" | npx wrangler secret put GOOGLE_CLIENT_ID echo "your-client-secret" | npx wrangler secret put GOOGLE_CLIENT_SECRET # Migrate remote database pnpm run db:migrate:remote # Build and deploy pnpm run build && pnpm run deploy ``` **Critical**: After first deploy, update BETTER_AUTH_URL with your actual Worker URL. Add the production URL to Google OAuth redirect URIs. ## Security Fingerprints Change all of these so attackers cannot identify your site uses this starter: | Location | Default Value | How to Change | |----------|---------------|---------------| | Page title | "Vite Flare Starter" | `index.html` | | App name in UI | "Vite Flare Starter" | `VITE_APP_NAME` env var | | localStorage keys | `vite-flare-starter-theme` | `VITE_APP_ID` env var | | API tokens | `vfs_` prefix | `VITE_TOKEN_PREFIX` env var | | GitHub links | starter repo | `VITE_GITHUB_URL` (set empty to hide) | | Worker name | `vite-flare-starter` | `wrangler.jsonc` | | Database name | `vite-flare-starter-db` | `wrangler.jsonc` | | R2 buckets | `vite-flare-starter-*` | `wrangler.jsonc` | ## Environment Variables ### Branding (VITE_ prefix = available in frontend) | Variable | Purpose | Example | |----------|---------|---------| | `VITE_APP_NAME` | Display name in UI | "My Cool App" | | `VITE_APP_ID` | localStorage prefix, Sentry | "mycoolapp" | | `VITE_TOKEN_PREFIX` | API token prefix | "mca_" | | `VITE_GITHUB_URL` | GitHub link (empty = hidden) | "" | | `VITE_FOOTER_TEXT` | Footer copyright text | "2026 My Company" | | `APP_NAME` | Server-side app name | "My Cool App" | ### Auth | Variable | Purpose | Notes | |----------|---------|-------| | `BETTER_AUTH_SECRET` | Session encryption | `openssl rand -hex 32` | | `BETTER_AUTH_URL` | Auth base URL | Must match actual URL exactly | | `TRUSTED_ORIGINS` | Allowed origins | Comma-separated, include localhost + prod | | `GOOGLE_CLIENT_ID` | Google OAuth | From Google Cloud Console | | `GOOGLE_CLIENT_SECRET` | Google OAuth | From Google Cloud Console | | `ENABLE_EMAIL_LOGIN` | Enable email/password | "true" to enable | | `ENABLE_EMAIL_SIGNUP` | Enable email signup | Requires ENABLE_EMAIL_LOGIN | ### Email (Optional) | Variable | Purpose | Notes | |----------|---------|-------| | `EMAIL_FROM` | Sender address | For verification/password reset | | `EMAIL_API_KEY` | Email service API key | Resend recommended | ## Common Customisations ### Adding a New Database Table 1. Add schema in `src/server/db/schema.ts` 2. Generate migration: `pnpm db:generate` 3. Apply locally: `pnpm db:migrate:local` 4. Apply to production: `pnpm db:migrate:remote` ### Adding a New API Route 1. Create route file in `src/server/routes/` 2. Register in `src/server/index.ts` 3. Add TanStack Query hook in `src/client/hooks/` ### Changing Auth Providers Edit `src/server/auth.ts`: add provider to `socialProviders`, add credentials to `.dev.vars` and production secrets, update client-side login buttons. ### Feature Flags Control features via environment variables: `VITE_FEATURE_STYLE_GUIDE=true`, `VITE_FEATURE_COMPONENTS=true`. Add your own in `src/client/lib/features.ts`. ## Troubleshooting | Symptom | Cause | Fix | |---------|-------|-----| | Auth redirects to homepage silently | Missing TRUSTED_ORIGINS | Set TRUSTED_ORIGINS with all valid URLs | | "Not authorized" on deploy | Wrong account_id | Remove account_id from wrangler.jsonc or set yours | | Database 500 errors | Missing migrations | Run `pnpm db:migrate:local` and `pnpm db:migrate:remote` | | localStorage shows "vite-flare-starter" | Missing VITE_APP_ID | Set `VITE_APP_ID=yourapp` in .dev.vars | | Auth fails in production only | BETTER_AUTH_URL mismatch | Must match actual Worker URL exactly (https, no trailing slash) | | "redirect_uri_mismatch" on Google sign-in | OAuth redirect URI missing | Add production URL to Google Cloud Console OAuth redirect URIs | | Secret changes have no effect | Not redeployed | `wrangler secret put` does NOT redeploy. Run `pnpm deploy` after | ## Production Deployment Checklist - [ ] `BETTER_AUTH_SECRET` set (different from dev!) - [ ] `BETTER_AUTH_URL` matches actual Worker URL - [ ] `TRUSTED_ORIGINS` includes all valid URLs - [ ] Google OAuth redirect URI includes production URL - [ ] Remote database migrated (`pnpm db:migrate:remote`) - [ ] No `vite-flare-starter` references in config files - [ ] Favicon replaced - [ ] CLAUDE.md updated - [ ] `.dev.vars` is NOT committed (check `.gitignore`)