Skip to content

Repository files navigation

Shorty — 开源 Serverless 短链接服务

一个基于 Cloudflare Pages 与 GitHub 的开源短链接管理工具。任何人都可以部署自己的短链接服务,无需维护服务器或数据库。


功能特性

  • 纯文件驱动:短链接规则存储在 GitHub 仓库的 _redirects 文件中,无需 KV、D1 或任何外部数据库。
  • 双模式重定向
    • 短链接:精确匹配(如 /abc → https://example.com
    • 命名空间:模式匹配,支持多级路径捕获(如 /b/** → https://blog.com/posts/:splats
  • 批量保存:控制台中多次操作暂存于本地,点击保存后一次性提交到 GitHub,节省构建次数。
  • 冲突检测:自动检测重复短码、命名空间与短链接的重叠冲突,以及并发修改冲突。
  • 双权限模式:支持个人模式(指定 GitHub 用户)或组织模式(指定 GitHub Organization 成员)。
  • 完全可配置:品牌名称、Logo、配色、域名等均通过 config.json 配置,构建时动态注入。

架构概览

/
├── _redirects # 短链接规则(由控制台自动维护)
├── index.html # 短域名根路径后备页
├── config.json # 品牌/部署配置
├── www/ # 控制台 + API
│ ├── src/ # React SPA 前端
│ ├── functions/ # Cloudflare Pages Functions (API + OAuth)
│ ├── public/ # 静态资源
│ └── package.json
└── README.md

双域名部署:

  • SHORT_DOMAIN(如 s.example.com):纯短链接域名,仅承载重定向。根路径 302 跳转到 WWW_DOMAIN
  • WWW_DOMAIN(如 www.example.com):介绍页 + 管理控制台(/admin 及子路由)。

两个 Cloudflare Pages 项目,绑定同一仓库的不同目录:

项目构建输出功能
短链接项目仓库根目录 ./_redirects + index.html
控制台项目www/distSPA + Pages Functions

快速开始

1. 创建 GitHub OAuth App

  1. 前往 GitHub Settings → Developer settings → OAuth Apps → New OAuth App
  2. 填写应用名称(如 Shorty
  3. Homepage URL: https://www.your-short.link
  4. Authorization callback URL: https://www.your-short.link/api/auth/callback
  5. 创建后记录 Client IDClient Secret

2. 创建数据仓库

  1. 创建一个新的 私有 GitHub 仓库(如 your-username/short-links-data
  2. 在仓库根目录创建 _redirects 文件,写入初始内容:
    / /index.html 302
    

3. Fork / 克隆本项目

将本仓库 Fork 到自己的账号下,或克隆后推送到自己的仓库。

4. 修改配置

编辑根目录 config.json

{
"brand": {
"name": "Shorty",
"tagline": "极简短链接服务",
"logoUrl": "/logo.svg",
"primaryColor": "#0969da"
},
"deployment": {
"shortDomain": "s.yourdomain.com",
"wwwDomain": "www.yourdomain.com",
"repoOwner": "your-github-username",
"repoName": "short-links-data",
"branch": "main"
}
}

5. 部署到 Cloudflare Pages

项目 A:短链接服务

  1. 在 Cloudflare Pages 创建新项目,连接 GitHub 仓库
  2. 构建输出目录/(仓库根目录)
  3. 无需构建命令
  4. 绑定自定义域名:s.yourdomain.com

项目 B:管理控制台

  1. 在同一仓库创建第二个 Pages 项目
  2. 构建输出目录www/dist
  3. 构建命令cd www && npm install && npm run build
  4. 绑定自定义域名:www.yourdomain.com
  5. 在 Pages 设置 → Functions 中,Functions 目录 设为 www/functions

6. 配置环境变量

在控制台项目(项目 B)的 Pages 设置 → Environment variables 中添加:

变量名说明示例
GITHUB_CLIENT_IDGitHub OAuth App 的 Client IDIv23lixxx...
GITHUB_CLIENT_SECRETGitHub OAuth App 的 Client Secretxxx...
SESSION_SECRET随机字符串,用于加密 session cookieopenssl rand -hex 32
CALLBACK_URLOAuth 回调地址https://www.yourdomain.com/api/auth/callback
AUTH_MODE权限模式:personalorgpersonal
ALLOWED_USERSpersonal 模式下允许的 GitHub 用户名(逗号分隔)octocat,alice
GITHUB_ORG_NAMEorg 模式下允许的 GitHub 组织名称my-org

注意AUTH_MODE 未设置时默认采用 org 模式;若无法确定则拒绝所有登录。


本地开发

前置要求

  • Node.js >= 20
  • pnpm

安装依赖

cd www
pnpm install

本地运行

# 启动 Vite 开发服务器
pnpm dev

前端将运行在 http://localhost:5173

注意:本地开发时 OAuth 回调和 Pages Functions 需要额外配置。建议使用 Cloudflare Wrangler 进行本地 Functions 开发:

# 安装 wrangler
npm install -g wrangler
# 在 www 目录下启动本地 Functions 开发
wrangler pages dev www --compatibility-date=2024-05-01

创建 www/.dev.vars 文件存放本地环境变量:

GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
SESSION_SECRET=your-session-secret
CALLBACK_URL=http://localhost:8788/api/auth/callback
AUTH_MODE=personal
ALLOWED_USERS=your-github-username

配置文件说明

根目录 config.json 在构建时被 Vite 读取并注入到前端代码中。无需重新构建即可修改品牌信息——只需修改文件并重新部署 Pages 项目即可。

字段说明
brand.name服务名称,显示在标题栏和页面中
brand.tagline标语,显示在介绍页
brand.logoUrlLogo 路径,建议放在 www/public/
brand.primaryColor主色调(当前设计系统使用粉色主题,此值预留用于未来扩展)
deployment.shortDomain短链接域名
deployment.wwwDomain控制台域名
deployment.repoOwner数据仓库的 GitHub 用户名/组织
deployment.repoName数据仓库名称
deployment.branch数据仓库分支

技术栈

  • 前端:Vite + React + TypeScript(严格模式)
  • 后端:Cloudflare Pages Functions(边缘计算)
  • 认证:GitHub OAuth 2.0 + Session Cookie
  • 数据存储:GitHub 仓库文件(_redirects
  • 设计系统:遵循 TransCircle 设计规范,支持 Light / Dark / Contrast 三种主题

许可证

本项目采用 AGPL-3.0 许可证开源。


贡献

欢迎提交 Issue 和 Pull Request。请遵循以下规范:

  • 分支命名:feat/scope/descriptionfix/scope/description
  • Commit Message::sparkles: feat(scope): add something
  • 新增代码必须通过 TypeScript 严格模式检查
  • 所有用户可见文本使用 i18n 函数包装
  • 为交互组件添加必要的 aria-label 和键盘支持

About

a serverless short link

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages