建 Cloudflare Named Tunnel 給本機 dev server(跨裝置 OAuth / webhook 測試用)。
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Charles5277/nuxt-supabase-starter --skill vite-tunnel --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Vite Tunnel?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/charles5277-vite-tunnel)More formats (shields.io, HTML) on the badges page.
---
name: vite-tunnel
description: 建 Cloudflare Named Tunnel 給本機 dev server(跨裝置 OAuth / webhook 測試用)。
disable-model-invocation: true
effort: medium
permission_tier: read-only
---
<!-- 🔒 LOCKED — managed by clade · auto-generated by sync-to-cursor; 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`。
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!