一个基于 Vue 3 + Vite + Cloudflare Workers + D1 + R2 的网址导航项目。
这个仓库可以直接开源自托管,但它当前带有示例数据、作者品牌文案和作者自己的域名配置。你在部署自己的版本前,需要先把这些默认值替换成自己的站点信息。
- 前端:
Vue 3+Vite+vue-router - 后端:
Cloudflare Workers - 数据库:
Cloudflare D1 - 图片存储:
Cloudflare R2 - 后台保护:
Cloudflare Access
- 页面静态资源由 Vite 构建到
dist - Worker 提供
/api/*、/admin和首页服务端注入逻辑 - 首页正文由 Worker 注入 HTML,爬虫拿到的不是空壳页
- 导航数据存储在 D1
- 站点 logo 存储在 R2,并通过公开自定义域名直接访问
/admin和/api/admin/*依赖 Cloudflare Access 保护
这个仓库默认包含以下作者相关内容:
- 站点域名:
oio.15tar.com - logo 域名:
oio-logos.15tar.com - 作者链接:
go.15tar.com - 作者名:
iStar
部署你自己的版本前,至少搜索并替换这些值:
rg -n "oio\.15tar\.com|oio-logos\.15tar\.com|go\.15tar\.com|iStar" src worker README.md wrangler.toml重点文件:
wrangler.tomlsrc/config/logos.tssrc/router/index.tssrc/components/SidebarMenu.vuesrc/components/AppFooter.vuesrc/views/HomeView.vuesrc/views/AboutView.vueworker/index.ts
公开投稿接口 /api/submissions 会把用户提交的网站信息转发到 Telegram。
如果你要保留这个功能,需要配置:
TELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
如果你不打算使用投稿功能:
- 可以不配置这两个 secret
- 但当前 UI 仍然会显示“我要投稿”,提交时接口会失败
- 最好同步移除或隐藏前端投稿入口
你需要准备:
- Node.js 22+
pnpm- 一个 Cloudflare 账号
- 一个你可控的域名
- 可选:Cloudflare Zero Trust,用于后台访问控制
pnpm installpnpm dev这个模式只启动 Vite,不包含 Worker、D1 和 R2。
pnpm build
pnpm cf:dev默认本地地址是:
http://127.0.0.1:8787http://localhost:8787
如果你希望继续用 pnpm dev 单独跑前端,同时把 API 指到本地 Worker,可以创建 .env.local:
VITE_API_BASE_URL=http://127.0.0.1:8787如果你要启用前端统计,再补上:
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
VITE_CLARITY_PROJECT_ID=xxxxxxxxxx说明:
VITE_GA_MEASUREMENT_ID是 GA4 的 Measurement ID,不再支持旧版UA-*VITE_CLARITY_PROJECT_ID是 Microsoft Clarity 项目 ID- 任一变量不填,对应脚本就不会注入
如果你使用 Cloudflare 的 Git 自动部署,这两个值应配置在 Cloudflare 项目的构建环境变量里,而不是写进仓库。
原因:
- 这两个
VITE_*变量在pnpm build阶段注入前端包 - 自动部署时,真正执行构建的是 Cloudflare
wrangler.toml的[vars]更适合 Worker 运行时变量,不能可靠替代前端构建期变量
如果你需要本地访问 /admin,创建 .dev.vars:
ADMIN_DEV_USER_EMAIL=local-dev@example.com
TELEGRAM_BOT_TOKEN=123456:example-token
TELEGRAM_CHAT_ID=123456789说明:
ADMIN_DEV_USER_EMAIL用于本地模拟后台身份TELEGRAM_*只在你要本地测试投稿时需要
先创建 D1 和 R2:
pnpm wrangler d1 create oio
pnpm wrangler r2 bucket create oio-logos
pnpm wrangler r2 bucket create oio-logos-preview你也可以改成自己的资源名,但要注意:
- 如果你修改了 D1 数据库名,记得同步修改
package.json里的cf:d1:migrate:*脚本 - 如果你修改了 bucket 名,记得同步修改
wrangler.toml
把 wrangler d1 create 返回的真实 database_id 写回 wrangler.toml。
同时把里面的路由改成你自己的站点域名,例如:
routes = [
{ pattern = "nav.example.com/", zone_name = "example.com" },
{ pattern = "nav.example.com/index.html", zone_name = "example.com" },
{ pattern = "nav.example.com/api/*", zone_name = "example.com" },
{ pattern = "nav.example.com/admin", zone_name = "example.com" },
{ pattern = "nav.example.com/admin/*", zone_name = "example.com" },
]这些根路径非常重要:
//index.html
项目当前依赖 Worker 接管首页请求,才能输出服务端注入后的正文 HTML。如果你漏掉这两个路由,首页会直接退回成静态壳页面。
这个项目默认假设 logo 通过公开 R2 域名直接访问,而不是走 Worker 代理。
你需要在 Cloudflare R2 里为 logo bucket 配一个公开域名,例如:
logos.example.com
配置完成后,更新 src/config/logos.ts:
export const PUBLIC_LOGO_BASE_URL = "https://logos.example.com";这个域名必须和你的 R2 public custom domain 保持一致,否则前端会请求错误的 logo 地址。
本地:
pnpm cf:d1:migrate:local远端:
pnpm cf:d1:migrate:remoteschema 位于 migrations/0001_navigation.sql。
至少考虑这些变量:
ADMIN_DEV_USER_EMAILTELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
线上推荐:
- 本地开发用
.dev.vars - 生产环境用
wrangler secret put
例如:
wrangler secret put TELEGRAM_BOT_TOKEN
wrangler secret put TELEGRAM_CHAT_ID说明:
ADMIN_DEV_USER_EMAIL只用于本地开发,不建议在线上依赖TELEGRAM_*不配置不会影响首页浏览,但会导致投稿接口不可用
推荐在 Cloudflare Zero Trust 里创建一个 Self-hosted application,至少保护:
/admin/admin/*/api/admin/*
Worker 会读取请求头:
Cf-Access-Authenticated-User-Email
作为后台身份来源。
如果你没给这些路径加 Cloudflare Access,生产环境里的 /admin 会因为拿不到身份而返回 401。
项目内置了一份示例导航数据:
当 D1 还是空库时,Worker 会自动把这份数据 bootstrap 进数据库。
这意味着你有两种选择:
- 在首次部署前就修改
src/data/navigation.ts为你自己的默认数据 - 先部署,再通过
/admin后台继续编辑
如果你不想让示例站点短暂出现在你的线上站点里,应该在首次远端 migration 和 deploy 前就先替换这份数据。
pnpm build
pnpm previewpnpm cf:deploy注意:
- 不要只把
dist当成纯静态站点部署 - 这个项目必须通过 Worker 发布,否则
/api/*、首页服务端注入、后台保护都会失效
当前 cf:deploy 已经带了:
wrangler deploy --keep-vars这样可以避免部署时把 Dashboard 中已有的普通 vars 清掉。
这个项目可以直接接 Cloudflare Workers 自带的 Git 自动部署,不依赖 GitHub Actions。
推荐配置:
- Build command:
pnpm build - Deploy command:
pnpm cf:deploy - Root directory:
/ - Production branch: 你的生产分支
注意:
- Cloudflare Build 的 “Variables and secrets” 只影响构建阶段
- Worker 运行时依赖的变量和 secret 仍然要在 Worker 自己的 Variables / Secrets 里配置
通常是这几类问题:
wrangler.toml没有把/和/index.html路由交给 Workerrun_worker_first没包含/和/index.html- 你把项目按纯静态站点部署了,而不是 Worker
通常是这几类问题:
- R2 bucket 没配置公开 custom domain
src/config/logos.ts里的PUBLIC_LOGO_BASE_URL还是原作者域名- R2 中对象 key 和数据库里的
icon_key不一致
通常是:
- 没配置 Cloudflare Access
- 访问路径不在受保护范围里
- 本地开发没设置
ADMIN_DEV_USER_EMAIL
通常是:
- 没配置
TELEGRAM_BOT_TOKEN - 没配置
TELEGRAM_CHAT_ID - Telegram bot 没有权限向目标 chat 发送消息
Cloudflare Git 自动部署不会自动帮你执行 D1 migration。
只要新增了 migration 文件,就要先手动运行:
pnpm cf:d1:migrate:remote然后再重新部署:
pnpm cf:deploy在你宣布站点可用前,至少确认以下项目:
- 域名、品牌文案、作者链接都已替换
wrangler.toml的 routes 已改成你的域名src/config/logos.ts的PUBLIC_LOGO_BASE_URL已改成你的 R2 域名- 远端 D1 migration 已执行
- R2 public custom domain 已生效
/能正常打开,并能看到真实正文而不是空壳/admin已被 Cloudflare Access 保护- 如果保留投稿功能,
TELEGRAM_*已配置完成