Skip to content

Commit 578b414

Browse files
vishrclaude
andcommitted
refactor(docs): generate redirect map instead of 63 inline entries
Move the /docs/* -> new-URL map into src/redirects.mjs, generated from the content tree (middleware/cookbook 1:1, flattened guide pages) plus a small explicit set for renamed/removed/category/search URLs. astro.config.mjs now just imports it. Same 63 entries / static redirect pages emitted; verified 64/64 live URLs still resolve and redirects fire end-to-end. (On a wildcard host like Cloudflare these collapse to ~6 _redirects lines.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1a063d5 commit 578b414

2 files changed

Lines changed: 40 additions & 68 deletions

File tree

site/astro.config.mjs

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,12 @@
11
import { defineConfig } from 'astro/config';
22
import starlight from '@astrojs/starlight';
3+
import { redirects } from './src/redirects.mjs';
34

45
// https://astro.build/config
56
export default defineConfig({
67
site: 'https://echo.labstack.com',
7-
// Preserve every live Docusaurus URL at cutover. The old site served docs under
8-
// /docs/... (flattened guide pages via slug overrides); Astro generates a static
9-
// meta-refresh page per entry (works on GitHub Pages — no _redirects needed).
10-
redirects: {
11-
'/docs': '/guide/quickstart/',
12-
'/docs/binding': '/guide/binding/',
13-
'/docs/category/cookbook': '/cookbook/hello-world/',
14-
'/docs/category/guide': '/guide/quickstart/',
15-
'/docs/category/middleware': '/middleware/basic-auth/',
16-
'/docs/cookbook/auto-tls': '/cookbook/auto-tls/',
17-
'/docs/cookbook/cors': '/cookbook/cors/',
18-
'/docs/cookbook/crud': '/cookbook/crud/',
19-
'/docs/cookbook/embed-resources': '/cookbook/embed-resources/',
20-
'/docs/cookbook/file-download': '/cookbook/file-download/',
21-
'/docs/cookbook/file-upload': '/cookbook/file-upload/',
22-
'/docs/cookbook/graceful-shutdown': '/cookbook/graceful-shutdown/',
23-
'/docs/cookbook/hello-world': '/cookbook/hello-world/',
24-
'/docs/cookbook/http2': '/cookbook/http2/',
25-
'/docs/cookbook/http2-server-push': '/cookbook/http2-server-push/',
26-
'/docs/cookbook/jsonp': '/cookbook/jsonp/',
27-
'/docs/cookbook/jwt': '/cookbook/jwt/',
28-
'/docs/cookbook/load-balancing': '/cookbook/load-balancing/',
29-
'/docs/cookbook/middleware': '/cookbook/middleware/',
30-
'/docs/cookbook/reverse-proxy': '/cookbook/reverse-proxy/',
31-
'/docs/cookbook/sse': '/cookbook/sse/',
32-
'/docs/cookbook/streaming-response': '/cookbook/streaming-response/',
33-
'/docs/cookbook/subdomain': '/cookbook/subdomain/',
34-
'/docs/cookbook/timeout': '/cookbook/timeout/',
35-
'/docs/cookbook/websocket': '/cookbook/websocket/',
36-
'/docs/cookies': '/guide/cookies/',
37-
'/docs/customization': '/guide/customization/',
38-
'/docs/error-handling': '/guide/error-handling/',
39-
'/docs/ip-address': '/guide/ip-address/',
40-
'/docs/middleware/basic-auth': '/middleware/basic-auth/',
41-
'/docs/middleware/body-dump': '/middleware/body-dump/',
42-
'/docs/middleware/body-limit': '/middleware/body-limit/',
43-
'/docs/middleware/casbin-auth': '/middleware/casbin-auth/',
44-
'/docs/middleware/context-timeout': '/middleware/context-timeout/',
45-
'/docs/middleware/cors': '/middleware/cors/',
46-
'/docs/middleware/csrf': '/middleware/csrf/',
47-
'/docs/middleware/decompress': '/middleware/decompress/',
48-
'/docs/middleware/gzip': '/middleware/gzip/',
49-
'/docs/middleware/jwt': '/middleware/jwt/',
50-
'/docs/middleware/key-auth': '/middleware/key-auth/',
51-
'/docs/middleware/logger': '/middleware/logger/',
52-
'/docs/middleware/method-override': '/middleware/method-override/',
53-
'/docs/middleware/open-telemetry': '/middleware/open-telemetry/',
54-
'/docs/middleware/prometheus': '/middleware/prometheus/',
55-
'/docs/middleware/proxy': '/middleware/proxy/',
56-
'/docs/middleware/rate-limiter': '/middleware/rate-limiter/',
57-
'/docs/middleware/recover': '/middleware/recover/',
58-
'/docs/middleware/redirect': '/middleware/redirect/',
59-
'/docs/middleware/request-id': '/middleware/request-id/',
60-
'/docs/middleware/rewrite': '/middleware/rewrite/',
61-
'/docs/middleware/secure': '/middleware/secure/',
62-
'/docs/middleware/session': '/middleware/session/',
63-
'/docs/middleware/static': '/middleware/static/',
64-
'/docs/middleware/trailing-slash': '/middleware/trailing-slash/',
65-
'/docs/quick-start': '/guide/quickstart/',
66-
'/docs/request': '/guide/request/',
67-
'/docs/response': '/guide/response/',
68-
'/docs/routing': '/guide/routing/',
69-
'/docs/start-server': '/guide/customization/',
70-
'/docs/static-files': '/guide/static-files/',
71-
'/docs/templates': '/guide/templates/',
72-
'/docs/testing': '/guide/testing/',
73-
'/search': '/',
74-
},
8+
// Preserve every live Docusaurus /docs/* URL at cutover (generated — see ./src/redirects.mjs).
9+
redirects,
7510
integrations: [
7611
starlight({
7712
title: 'Echo',

site/src/redirects.mjs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { readdirSync } from 'node:fs';
2+
import { fileURLToPath } from 'node:url';
3+
4+
// Old Docusaurus URLs -> new locations, generated so astro.config stays small.
5+
// The old site served docs under /docs/ with guide pages flattened (slug
6+
// overrides). On GitHub Pages each entry still emits its own static
7+
// meta-refresh page (no server-side wildcards) — that's why there are ~60.
8+
// On a wildcard-capable host (Cloudflare/Netlify) these collapse to a handful
9+
// of `_redirects` lines.
10+
11+
const docsDir = fileURLToPath(new URL('./content/docs', import.meta.url));
12+
const pages = (sub) =>
13+
readdirSync(`${docsDir}/${sub}`)
14+
.filter((f) => /\.mdx?$/.test(f))
15+
.map((f) => f.replace(/\.mdx?$/, ''));
16+
17+
// Guide pages were flattened to /docs/<name>. Exclude pages that have no old
18+
// URL (new in v5) or are handled explicitly below.
19+
const GUIDE_SKIP = new Set(['context', 'installation', 'quickstart']);
20+
21+
const fromList = (subPrefix, toPrefix, names) =>
22+
Object.fromEntries(names.map((n) => [`/docs/${subPrefix}${n}`, `/${toPrefix}${n}/`]));
23+
24+
export const redirects = {
25+
// Renamed, removed, index, Docusaurus category pages, and the old search page.
26+
'/docs': '/guide/quickstart/',
27+
'/docs/quick-start': '/guide/quickstart/',
28+
'/docs/start-server': '/guide/customization/',
29+
'/docs/category/guide': '/guide/quickstart/',
30+
'/docs/category/middleware': '/middleware/basic-auth/',
31+
'/docs/category/cookbook': '/cookbook/hello-world/',
32+
'/search': '/',
33+
// Bulk, generated from the current content tree.
34+
...fromList('', 'guide/', pages('guide').filter((n) => !GUIDE_SKIP.has(n))),
35+
...fromList('middleware/', 'middleware/', pages('middleware')),
36+
...fromList('cookbook/', 'cookbook/', pages('cookbook')),
37+
};

0 commit comments

Comments
 (0)