在 Vite dev server 前掛 Cloudflare Named Tunnel,給固定 HTTPS hostname。Use when 跨裝置(手機 / 平板 / 另一台筆電)測 OAuth flow、跨裝置測 webhook callback、行動裝置 debug 需要穩定 HTTPS URL、Vite 加 Cloudflare tunnel、設定 dev HTTPS hostname、改 OAuth callback 不想每次回 provider 後台。對 Workers/Pages 用官方 @cloudflare/vite-plugin 內建 tunnel;對一般 Vite 走第三方 vite-plugin-cloudflare-tunnel。不適用於 prod tunnel(這 skill 只管 dev)、其他 provider(ngrok / localtunnel)、單機開發夠用的情境(用 vendor/snippets/dev-auth/ cookbook 繞 OAuth 更快)、需要 quick tunnel 隨機 hostname 的場景(直接跑 cl...
Scanned 6/6/2026
Install via CLI
openskills install YuDefine/nuxt-supabase-starter---
name: vite-tunnel
description: 在 Vite dev server 前掛 Cloudflare Named Tunnel,給固定 HTTPS hostname。Use when 跨裝置(手機 / 平板 / 另一台筆電)測 OAuth flow、跨裝置測 webhook callback、行動裝置 debug 需要穩定 HTTPS URL、Vite 加 Cloudflare tunnel、設定 dev HTTPS hostname、改 OAuth callback 不想每次回 provider 後台。對 Workers/Pages 用官方 @cloudflare/vite-plugin 內建 tunnel;對一般 Vite 走第三方 vite-plugin-cloudflare-tunnel。不適用於 prod tunnel(這 skill 只管 dev)、其他 provider(ngrok / localtunnel)、單機開發夠用的情境(用 vendor/snippets/dev-auth/ cookbook 繞 OAuth 更快)、需要 quick tunnel 隨機 hostname 的場景(直接跑 cloudflared tunnel --url 即可,不必走這 skill)。
effort: medium
---
<!-- 🔒 LOCKED — managed by clade · auto-generated by sync-to-agents; edit source in .claude/ then re-run sync -->
對應 cookbook:`~/offline/clade/vendor/snippets/vite-tunnel/`
## 何時用 vs 何時不用
**用這個 skill**:
- 真實 OAuth provider flow 必須跑(Apple Sign In、不能 mock、要驗 production-like cookie flow)
- 手機 / 平板 / 另一台筆電要連 dev server 跑 OAuth callback / webhook
- 對外人秀 dev preview,需要穩定 hostname
**改走其他做法**:
- 單機開發 + Claude 並行驗證 → 用 `vendor/snippets/dev-auth/` cookbook 繞 OAuth(更快、不依賴外部網路)
- 短時間 webhook 測試(5 分鐘解決)→ `cloudflared tunnel --url http://localhost:5173` 拿 quick tunnel,OAuth 註冊壞掉沒關係因為時間短
- 多 worktree 並行 dev server → dev-auth + cookie namespace 比 tunnel 簡單
## Step 1: 偵測專案部署 target
讀 `package.json` / `wrangler.toml` / `wrangler.jsonc`:
| 偵測信號 | 路線 | 後續 |
| --- | --- | --- |
| 有 `wrangler.toml` / `wrangler.jsonc`,或 `@cloudflare/vite-plugin` 在 deps | **官方路線** | `@cloudflare/vite-plugin` 內建,按 `t + Enter` 拉 tunnel |
| 一般 Vite 專案(純 SPA / Vite SSR) | **第三方路線** | 裝 `vite-plugin-cloudflare-tunnel` |
```bash
# 偵測指令參考
test -f wrangler.toml || test -f wrangler.jsonc && echo "Workers project"
grep -q '"@cloudflare/vite-plugin"' package.json && echo "Workers project"
```
## Step 2: 前置檢查
跟使用者確認:
1. Domain 是否**掛在 Cloudflare DNS**(nameserver 切過去;不只 zone delegated)
2. `cloudflared` CLI 已裝(`brew install cloudflared`)
3. 已登入:`cloudflared tunnel login`(看 `~/.cloudflared/cert.pem` 存在)
4. **同時管多 Cloudflare account 的話**:跑 `cloudflared tunnel list` 確認當前 cert.pem 對應的是預期 account(看 tunnel 名稱判:`yudefine-*` / `perno-dev` / `rental-scout-*` 屬 YuDefine;`ehr-*` / `justech-*` / `ms2-*` 屬 BigByte)。綁錯會踩 multi-account silent CNAME misdirection — `route dns` exit 0 但 hostname 被附加到別 account 內第一個 zone。詳見 cookbook `## 多 Cloudflare account 使用情境` 段 + `docs/pitfalls/2026-05-21-cloudflared-multi-account-cname-misdirection.md`
任一缺失就停下來提示使用者補齊,不要硬推進。
`dev-tunnel-setup.sh` 跑時也會自動驗 zone-in-account(用 `CLOUDFLARE_API_KEY`):命中印確認訊息繼續、0 命中 fail-loud 列三條出路、token 未設則 skip + warn。雙保險(文件層 + 程式層)。
## Step 3: 取得 API token
- **官方路線**:不需要 API token(plugin 走 `cert.pem` 認證),跳到 Step 4
- **第三方路線**:需要
從 **Notion** 找「Cloudflare DNS+Tunnel token」。沒這頁的話:
1. 跟使用者確認要新建 token
2. 提示 Cloudflare dashboard 路徑:My Profile → API Tokens → Create Token
3. Scope: `Account → Cloudflare Tunnel → Edit` + `Zone → DNS → Edit`(建議 apply to All zones 省得未來重發)
4. 拿到 token 後請使用者存進 Notion 再貼進 `.env.local`
## Step 4: 跑 setup 腳本
```bash
~/offline/clade/vendor/snippets/vite-tunnel/bin/dev-tunnel-setup.sh \
<hostname> <tunnel-name>
```
約定 tunnel-name = `<project>-dev`(如 `perno-dev`、`tdms-dev`)。
腳本會:
1. 偵測 cloudflared / cert.pem,缺則停手指示
2. `cloudflared tunnel create <name>`(idempotent,已存在則重用)
3. `cloudflared tunnel route dns <name> <hostname>`
4. 寫 / 補 `.env.local`(不覆蓋既有值):`TUNNEL_HOSTNAME` / `TUNNEL_NAME` / `TUNNEL_ID` / `CLOUDFLARE_API_KEY`(空值待填)
## Step 5: 填 token + patch vite.config
### 第三方路線
1. 填 token:把 Notion 拿到的字串貼進 `.env.local` 的 `CLOUDFLARE_API_KEY=`(注意是 `KEY` 不是 `TOKEN`,第三方 plugin 慣例命名)
2. 安裝 plugin:
```bash
pnpm add -D vite-plugin-cloudflare-tunnel
```
3. 抄範本:把 `~/offline/clade/vendor/snippets/vite-tunnel/templates/vite.config.generic.snippet.ts.template` 對應段合進 `vite.config.ts`。重點兩塊:
- `plugins: [..., cloudflareTunnel({ hostname, tunnelName, apiToken })]`
- `server: { allowedHosts: [hostname] }`
不要直接覆蓋使用者既有 `vite.config.ts`——只 merge 必要兩塊。
### 官方路線(Workers/Pages)
抄範本:`~/offline/clade/vendor/snippets/vite-tunnel/templates/vite.config.workers.snippet.ts.template`,重點是 `cloudflare({ tunnel: { name: '<tunnel-name>' } })`。`vite dev` 模式 plugin 會自動處理 host 驗證;`vite preview` 才要手動補 `preview.allowedHosts`。
## Step 6: OAuth provider 註冊 callback
提示使用者去 provider 後台(依專案 stack 不同)補 callback URL:
| Provider | 通常路徑 |
| --- | --- |
| Google OAuth | Google Cloud Console → APIs & Services → Credentials → OAuth client → Authorized redirect URIs |
| GitHub OAuth App | GitHub Settings → Developer settings → OAuth Apps → Authorization callback URL |
| Supabase Auth | Supabase dashboard → Authentication → URL Configuration → Redirect URLs |
| Apple Sign In | Apple Developer → Identifiers → Services IDs → Return URLs |
新加一筆 `https://<hostname>/auth/callback`(**不**動既有 localhost 那筆,dev 兩用)。
## Step 7: 啟動 + 驗證
```bash
pnpm dev
# 官方路線:按 t + Enter 拉 tunnel
# 第三方路線:plugin 自動拉,等 ready log
curl -I https://<hostname> # 預期 200 / 301
```
驗收:
- [ ] `curl -I https://<hostname>` 通
- [ ] 桌面瀏覽器開 `https://<hostname>` 看到 dev server 頁面
- [ ] 手機 / 另一裝置開 `https://<hostname>` 跑完 OAuth flow,登入成功
- [ ] 登入後 reload 頁面 session 還在(cookie Secure 正常)
任一條沒過,去看 cookbook 的 Gotchas 表(`vendor/snippets/vite-tunnel/README.md`)。
## 共用 tunnel 模型
**每專案各建一條 tunnel**(不要把多專案 hostname route 到同一 tunnel):
- tunnel-name 跟專案 name 綁定(`perno-dev` / `tdms-dev`)
- A 專案 dev 關閉時 B 不會被牽連 502
- `cloudflared tunnel list` 一目了然
Token 是**全 account 共用一張**(SoT 在 Notion;scope 足夠就跨 zone/跨專案 work)。
## Gotchas(精簡版,完整看 cookbook)
- `server.allowedHosts` 漏 hostname → Vite 回 "Blocked request";第三方路線**必加**
- OAuth callback 仍指 localhost → provider 回 `redirect_uri_mismatch`
- Cookie 沒 `Secure` flag → 跨裝置登入後 session 立刻丟
- Token 缺 `Cloudflare Tunnel:Edit` scope → `route dns` 通但 `tunnel create` 報 403
- Domain 不在 Cloudflare DNS → `route dns` 報 zone not found
- 用 `cloudflared tunnel --url` 拉 quick tunnel → hostname 隨機,OAuth 註冊壞掉;這 skill **MUST** 用 named tunnel
- 對外人分享 dev URL → 用 `vite preview` 而非 `vite dev`(HMR / source files 不對外洩)
完整解法看 `~/offline/clade/vendor/snippets/vite-tunnel/README.md#gotchas`。
No comments yet. Be the first to comment!