Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 12 additions & 27 deletions .github/workflows/pages-build-site.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
name: pages-build-site
on:
# The editor now lives at https://edit.chaxus.com (Cloudflare Pages).
# GitHub Pages publishes ONLY a client-side redirector (redirect/), so old
# ranuts.github.io/document/* links keep working (path + query preserved).
# The app now deploys to Cloudflare Pages from `main`, so GitHub Pages is
# main-based too: any push to main republishes the redirector. workflow_dispatch
# lets you trigger the first redirector deploy by hand once Cloudflare is live.
push:
branches:
- release/v0.0.4
- main
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
Expand All @@ -16,40 +23,18 @@ concurrency:

jobs:
build:
name: Build
name: Publish redirector
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6

- uses: pnpm/action-setup@v6
name: Install pnpm
id: pnpm-install
with:
run_install: false

- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build
run: pnpm build
env:
# Cloudflare Web Analytics beacon token (public client-side value).
# Set it under Settings → Secrets and variables → Actions → Variables.
# Unset → analytics is tree-shaken out and the site ships tracking-free.
VITE_CF_BEACON_TOKEN: ${{ vars.VITE_CF_BEACON_TOKEN }}

- name: Upload artifact
# No build: just ship the static redirector (redirect/index.html + 404.html).
- name: Upload redirector artifact
uses: actions/upload-pages-artifact@v5
with:
path: "./dist"
path: "./redirect"

deploy:
name: Deploy to GitHub Pages
Expand Down
52 changes: 52 additions & 0 deletions docs/explorations/2026-07-05-github-pages-redirector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# GitHub Pages 跳转器 → edit.chaxus.com(带参数,准备件,暂不激活)

> 2026-07-05

## 背景

document 迁到 `edit.chaxus.com`(Cloudflare Pages)后,旧地址 `ranuts.github.io/document/*` 要保持可用并把 SEO 权重转过去。github.io 是 GitHub 域名,只能**客户端跳转**(JS `location.replace` + canonical,Google 视同 301)。

## 关键先决:document 已经 base 无关(ran 的根路径化对它是 no-op)

核实后发现 document 与 ran 不同,**不需要**「base `/document/` → `/`」的代码工:

- `vite.config.ts` base = `'./'`(相对,资源不带前缀)
- `getBasePath()` 是**运行时**从 `window.location.pathname` 判断:`/document/` 开头→`/document/`,否则→`/`。在 `edit.chaxus.com` 根域上 pathname=`/` → 自动返回 `/`
- `manifest.json`:`start_url:"./"` + 图标相对路径,无绝对 `/document/`
- SW 注册:`register('./sw.js')` 相对 → scope 随部署路径自适应

→ 迁到根域后 wasm/字体/manifest/SW 全自动适配,**代码零改动**。(planning 决策 6 里"必做代码工"整条勾销。)

## 跳转器实现

`redirect/index.html` + `redirect/404.html`(内容一致,GitHub Pages 对未匹配路径回 404.html)。核心 JS:

```js
var base = 'https://edit.chaxus.com';
var path = location.pathname.replace(/^\/document/, '') || '/';
var link = document.querySelector('link[rel=canonical]');
if (link) link.href = base + path + location.search;
location.replace(base + path + location.search + location.hash);
```

**为什么必须带参数**:编辑器靠 `?embed=` / `?embedded=` / `?agent=1` / `?url=` / `?embedOrigin=` 驱动,query 丢了 embed/agent 全废。所以保留「去 `/document` 前缀的 path + `location.search` + `location.hash`」。canonical 也按目标路径动态设;无 JS 时用静态 `meta refresh` 兜底到根(静态无法算 path,小站够用)。

## workflow 改造

`.github/workflows/pages-build-site.yml`:去掉 pnpm/node/install/build,只 `upload-pages-artifact` 发布 `./redirect` 目录。触发分支从 `release/v0.0.4` 改为 **`main`**(CF 现从 main 部署 app,GH Pages 也统一到 main);加 `workflow_dispatch` 便于 CF 上线后手动触发首发。注意 `release/v0.0.4` 仍是 v7 维护线,只是 CI 不再依赖它、分支保留。

## 验证

- **6 个用例(node)**:路径剥离 + query + hash 组合,目标 URL 全部正确
- **真浏览器(Playwright)**:拦截 `ranuts.github.io/document/*` 返回跳转器,捕获实际跳转目标 —— `?embed=1` / `?agent=1&url=...` / 深层路径 `?embedOrigin=...#sec` 全部正确剥离前缀并保留 query

## ⚠️ 激活时机(不可提前)

**本 PR 是准备件,CF 新站 `edit.chaxus.com` 确认上线前不可合并/激活。** 否则会把用户导去尚不存在的站。顺序(照 ran 踩坑):

1. 先上 `edit.chaxus.com`(CF `*.pages.dev` 验证 OK)
2. 合并本 PR → workflow 改为发跳转器(**不能直接删 workflow**,否则 GH Pages 冻结旧站 → 重复内容打架)
3. `workflow_dispatch` 手动触发首发,验证 `ranuts.github.io/document/` → 302/JS 跳 `edit.chaxus.com`
4. GSC 地址变更 / sitemap / 外链

**触发分支已统一到 `main`**(原 `release/v0.0.4`):CF 现从 main 部署 app,GH Pages 也随之 main-based → 合并本 PR 到 main 即激活。`release/v0.0.4` 仍是 v7 维护线,分支保留,只是 CI 不再依赖它。
35 changes: 35 additions & 0 deletions redirect/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Moved to edit.chaxus.com</title>
<!-- The editor moved from ranuts.github.io/document to https://edit.chaxus.com.
This page is only a redirector left behind so old links keep working.
Google treats JS location.replace + canonical as a soft 301. -->
<link rel="canonical" href="https://edit.chaxus.com/" />
<script>
(function () {
var base = 'https://edit.chaxus.com';
// Strip the GitHub Pages base ("/document") and keep the rest of the
// path. Query + hash MUST be preserved — the editor is driven by params
// like ?embed= / ?embedded= / ?agent=1 / ?url= / ?embedOrigin=, and a
// dropped query would silently break embed / agent flows.
var path = location.pathname.replace(/^\/document/, '') || '/';
var canonical = base + path + location.search;
var link = document.querySelector('link[rel=canonical]');
if (link) link.href = canonical;
location.replace(base + path + location.search + location.hash);
})();
</script>
<!-- Fallback for crawlers / JS-disabled clients. Static, so it can only
point at the root; the script above handles per-path redirects. -->
<meta http-equiv="refresh" content="0; url=https://edit.chaxus.com/" />
</head>
<body>
<p>
This editor has moved to
<a href="https://edit.chaxus.com/">edit.chaxus.com</a>. Redirecting…
</p>
</body>
</html>
35 changes: 35 additions & 0 deletions redirect/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Moved to edit.chaxus.com</title>
<!-- The editor moved from ranuts.github.io/document to https://edit.chaxus.com.
This page is only a redirector left behind so old links keep working.
Google treats JS location.replace + canonical as a soft 301. -->
<link rel="canonical" href="https://edit.chaxus.com/" />
<script>
(function () {
var base = 'https://edit.chaxus.com';
// Strip the GitHub Pages base ("/document") and keep the rest of the
// path. Query + hash MUST be preserved — the editor is driven by params
// like ?embed= / ?embedded= / ?agent=1 / ?url= / ?embedOrigin=, and a
// dropped query would silently break embed / agent flows.
var path = location.pathname.replace(/^\/document/, '') || '/';
var canonical = base + path + location.search;
var link = document.querySelector('link[rel=canonical]');
if (link) link.href = canonical;
location.replace(base + path + location.search + location.hash);
})();
</script>
<!-- Fallback for crawlers / JS-disabled clients. Static, so it can only
point at the root; the script above handles per-path redirects. -->
<meta http-equiv="refresh" content="0; url=https://edit.chaxus.com/" />
</head>
<body>
<p>
This editor has moved to
<a href="https://edit.chaxus.com/">edit.chaxus.com</a>. Redirecting…
</p>
</body>
</html>