Skip to content

Commit c8ed486

Browse files
Merge pull request #71 from a-thomas-22/at/elegant-tharp-025639
fix(redirects): serve legacy URL redirects in production via vercel.json
2 parents 5e6581f + 8b3b59b commit c8ed486

7 files changed

Lines changed: 1358 additions & 305 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: redirects-in-sync
2+
3+
# Guarantees vercel.json matches redirects.config.js (the single source of
4+
# truth). Vercel reads vercel.json at the start of a deployment, so a commit
5+
# that edits redirects.config.js without regenerating vercel.json would ship
6+
# stale production redirects. This job regenerates the file and fails if it
7+
# differs from what's committed.
8+
9+
on:
10+
pull_request:
11+
push:
12+
branches: [main]
13+
14+
jobs:
15+
check:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: 20
22+
23+
# No `npm install` needed: the sync script uses only Node built-ins and
24+
# imports the local redirects.config.js.
25+
- name: Regenerate vercel.json from redirects.config.js
26+
run: node scripts/sync-vercel-redirects.mjs
27+
28+
- name: Fail if vercel.json is out of date
29+
run: |
30+
if [ -n "$(git status --porcelain vercel.json)" ]; then
31+
echo "::error::vercel.json is out of sync with redirects.config.js. Run 'npm run sync-redirects' and commit the result."
32+
git --no-pager diff vercel.json
33+
exit 1
34+
fi
35+
echo "vercel.json is in sync with redirects.config.js."

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"type": "module",
44
"scripts": {
55
"dev": "vocs dev",
6+
"sync-redirects": "node scripts/sync-vercel-redirects.mjs",
7+
"prebuild": "node scripts/sync-vercel-redirects.mjs",
68
"build": "vocs build",
79
"preview": "vocs preview",
810
"format": "prettier --write ."

redirects.config.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface DocRedirect {
2+
from: string;
3+
to: string;
4+
}
5+
6+
export declare const redirects: DocRedirect[];

redirects.config.js

Lines changed: 252 additions & 0 deletions
Large diffs are not rendered by default.

scripts/sync-vercel-redirects.mjs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* sync-vercel-redirects — mirror redirects.config.js into vercel.json.
3+
*
4+
* The list in redirects.config.js is the single source of truth. Vocs only
5+
* applies it in local dev (via the middleware in vocs.config.tsx), so this
6+
* script mirrors it into vercel.json so Vercel serves the redirects in
7+
* production. Vercel reads vercel.json at the start of a deployment (before the
8+
* build command runs), so the generated file is committed.
9+
*
10+
* Run with `npm run sync-redirects` (also runs on `npm run build` via prebuild).
11+
*
12+
* Patterned on OffchainLabs/arbitrum-docs (scripts/sync-vercel-redirects.ts).
13+
* That repo splices a sentinel-bounded block into a hand-maintained vercel.json
14+
* to coexist with manual entries; ZeroDev's vercel.json is fully generated, so
15+
* here we (re)write it wholesale. Written as `.mjs` because this repo has no
16+
* `tsx`; it imports the `.js` config natively.
17+
*/
18+
19+
import { writeFile } from "node:fs/promises";
20+
import path from "node:path";
21+
import { fileURLToPath } from "node:url";
22+
23+
import { redirects } from "../redirects.config.js";
24+
25+
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
26+
const vercelPath = path.join(root, "vercel.json");
27+
28+
// permanent: false -> 307, matching the arbitrum-docs convention. Temporary
29+
// redirects aren't cached aggressively by browsers/crawlers, which keeps future
30+
// doc reorganizations easy to revert.
31+
const json =
32+
JSON.stringify(
33+
{
34+
redirects: redirects.map(({ from, to }) => ({
35+
source: from,
36+
destination: to,
37+
permanent: false,
38+
})),
39+
},
40+
null,
41+
2,
42+
) + "\n";
43+
44+
await writeFile(vercelPath, json);
45+
console.log(`sync-redirects: wrote ${redirects.length} redirects into vercel.json.`);

0 commit comments

Comments
 (0)