| 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 |
對應 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 |
test -f wrangler.toml || test -f wrangler.jsonc && echo "Workers project"
grep -q '"@cloudflare/vite-plugin"' package.json && echo "Workers project"
Step 2: 前置檢查
跟使用者確認:
- Domain 是否掛在 Cloudflare DNS(nameserver 切過去;不只 zone delegated)
cloudflared CLI 已裝(brew install cloudflared)
- 已登入:
cloudflared tunnel login(看 ~/.cloudflared/cert.pem 存在)
- 同時管多 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」。沒這頁的話:
- 跟使用者確認要新建 token
- 提示 Cloudflare dashboard 路徑:My Profile → API Tokens → Create Token
- Scope:
Account → Cloudflare Tunnel → Edit + Zone → DNS → Edit(建議 apply to All zones 省得未來重發)
- 拿到 token 後請使用者存進 Notion 再貼進
.env.local
Step 4: 跑 setup 腳本
~/offline/clade/vendor/snippets/vite-tunnel/bin/dev-tunnel-setup.sh \
<hostname> <tunnel-name>
約定 tunnel-name = <project>-dev(如 perno-dev、tdms-dev)。
腳本會:
- 偵測 cloudflared / cert.pem,缺則停手指示
cloudflared tunnel create <name>(idempotent,已存在則重用)
cloudflared tunnel route dns <name> <hostname>
- 寫 / 補
.env.local(不覆蓋既有值):TUNNEL_HOSTNAME / TUNNEL_NAME / TUNNEL_ID / CLOUDFLARE_API_KEY(空值待填)
Step 5: 填 token + patch vite.config
第三方路線
-
填 token:把 Notion 拿到的字串貼進 .env.local 的 CLOUDFLARE_API_KEY=(注意是 KEY 不是 TOKEN,第三方 plugin 慣例命名)
-
安裝 plugin:
pnpm add -D vite-plugin-cloudflare-tunnel
-
抄範本:把 ~/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: 啟動 + 驗證
pnpm dev
curl -I https://<hostname>
驗收:
任一條沒過,去看 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。