Skip to content

Commit 9be85b6

Browse files
Programcodeclaude
andcommitted
Drop the trailing-slash guide redirects that never match
On the preview, /debate-weighing-guide/ gets the trailingSlash 308 to /debate-weighing-guide before any redirect rule runs, then the 301 to /how-to-weigh-in-debate. The /<slug>/ rules never fire, so remove them and say in operations.md how slash URLs reach the survivor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent eea9607 commit 9be85b6

3 files changed

Lines changed: 2 additions & 67 deletions

File tree

‎docs/operations.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Vercel builds and serves the frontend from the Git repository. Merging to `main`
4444
- rewrites of the app routes (`/app`, `/login`, `/share`, `/expocit/sources`) to `app-shell.html`; any other path that is not a file gets `404.html` with a real 404 status;
4545
- `trailingSlash: false`, which 308-redirects `/app/settings/` to `/app/settings` before routing, since rewrite and redirect sources match exactly;
4646
- 301 redirects from the retired brand pages (`/debatelab`, `/debatelab-by-programcode`, and the rest) to `/`;
47-
- 301 redirects from retired guide slugs to the guide that replaced them, such as `/debate-weighing-guide` to `/how-to-weigh-in-debate`, one rule each for the path with and without a trailing slash;
47+
- 301 redirects from retired guide slugs to the guide that replaced them, such as `/debate-weighing-guide` to `/how-to-weigh-in-debate`. The `trailingSlash` 308 runs first, so `/debate-weighing-guide/` reaches the same page in two permanent hops and needs no rule of its own;
4848
- no-cache headers for `/`, `index.html`, `app-shell.html`, `theme-init.js`, and `sw.js`, and immutable caching for hashed `/assets/`;
4949
- `noindex` headers for `/app`, `/login`, and `/share` routes;
5050
- Content Security Policy and the other response security headers, including the `Permissions-Policy` that allows the microphone for the app's own origin only.

‎src/test/vercel-deployment-config.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe("Vercel frontend deployment configuration", () => {
6060

6161
it("redirects each retired guide to a live guide that no page links past", () => {
6262
const guideRedirects = (loadConfig().redirects ?? []).filter((rule) => !rule.source.startsWith("/:page("));
63-
const retired = new Set(guideRedirects.map((rule) => rule.source.replace(/\/$/, "")));
63+
const retired = new Set(guideRedirects.map((rule) => rule.source));
6464
const pages = readdirSync(resolve(process.cwd(), "public"), { withFileTypes: true })
6565
.filter((entry) => entry.isDirectory() && existsSync(resolve(process.cwd(), "public", entry.name, "index.html")))
6666
.map((entry) => `/${entry.name}`);

‎vercel.json‎

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,130 +25,65 @@
2525
"destination": "/online-debate-timer",
2626
"statusCode": 301
2727
},
28-
{
29-
"source": "/online-debate-timer-tool/",
30-
"destination": "/online-debate-timer",
31-
"statusCode": 301
32-
},
3328
{
3429
"source": "/debate-argument-flowchart-tool",
3530
"destination": "/argument-flowchart",
3631
"statusCode": 301
3732
},
38-
{
39-
"source": "/debate-argument-flowchart-tool/",
40-
"destination": "/argument-flowchart",
41-
"statusCode": 301
42-
},
4333
{
4434
"source": "/debate-weighing-guide",
4535
"destination": "/how-to-weigh-in-debate",
4636
"statusCode": 301
4737
},
48-
{
49-
"source": "/debate-weighing-guide/",
50-
"destination": "/how-to-weigh-in-debate",
51-
"statusCode": 301
52-
},
5338
{
5439
"source": "/debate-impact-calculus",
5540
"destination": "/how-to-weigh-in-debate",
5641
"statusCode": 301
5742
},
58-
{
59-
"source": "/debate-impact-calculus/",
60-
"destination": "/how-to-weigh-in-debate",
61-
"statusCode": 301
62-
},
6343
{
6444
"source": "/debate-cross-examination-tips",
6545
"destination": "/how-to-cross-examine-in-debate",
6646
"statusCode": 301
6747
},
68-
{
69-
"source": "/debate-cross-examination-tips/",
70-
"destination": "/how-to-cross-examine-in-debate",
71-
"statusCode": 301
72-
},
7348
{
7449
"source": "/debate-note-taking-flowing",
7550
"destination": "/how-to-flow-in-debate",
7651
"statusCode": 301
7752
},
78-
{
79-
"source": "/debate-note-taking-flowing/",
80-
"destination": "/how-to-flow-in-debate",
81-
"statusCode": 301
82-
},
8353
{
8454
"source": "/debate-case-generator",
8555
"destination": "/ai-debate-case-generator",
8656
"statusCode": 301
8757
},
88-
{
89-
"source": "/debate-case-generator/",
90-
"destination": "/ai-debate-case-generator",
91-
"statusCode": 301
92-
},
9358
{
9459
"source": "/how-to-write-a-rebuttal-speech",
9560
"destination": "/how-to-practice-rebuttals",
9661
"statusCode": 301
9762
},
98-
{
99-
"source": "/how-to-write-a-rebuttal-speech/",
100-
"destination": "/how-to-practice-rebuttals",
101-
"statusCode": 301
102-
},
10363
{
10464
"source": "/wsdc-debate-practice",
10565
"destination": "/world-schools-debate",
10666
"statusCode": 301
10767
},
108-
{
109-
"source": "/wsdc-debate-practice/",
110-
"destination": "/world-schools-debate",
111-
"statusCode": 301
112-
},
11368
{
11469
"source": "/ai-debate-evidence-research",
11570
"destination": "/debate-evidence-finder",
11671
"statusCode": 301
11772
},
118-
{
119-
"source": "/ai-debate-evidence-research/",
120-
"destination": "/debate-evidence-finder",
121-
"statusCode": 301
122-
},
12373
{
12474
"source": "/debate-evidence-verification",
12575
"destination": "/debate-evidence-finder",
12676
"statusCode": 301
12777
},
128-
{
129-
"source": "/debate-evidence-verification/",
130-
"destination": "/debate-evidence-finder",
131-
"statusCode": 301
132-
},
13378
{
13479
"source": "/debatelab-alternatives",
13580
"destination": "/best-ai-debate-tools",
13681
"statusCode": 301
13782
},
138-
{
139-
"source": "/debatelab-alternatives/",
140-
"destination": "/best-ai-debate-tools",
141-
"statusCode": 301
142-
},
14383
{
14484
"source": "/ai-tools-for-debate-students",
14585
"destination": "/best-ai-debate-tools",
14686
"statusCode": 301
147-
},
148-
{
149-
"source": "/ai-tools-for-debate-students/",
150-
"destination": "/best-ai-debate-tools",
151-
"statusCode": 301
15287
}
15388
],
15489
"rewrites": [

0 commit comments

Comments
 (0)