Skip to content

Commit a339967

Browse files
Mlaz-codepaperclip-resolver[bot]claude
authored
fix(seo): add trailing-slash redirect variants for bare docs paths (#245)
Vercel's trailingSlash:true rewrites /foo → /foo/ before evaluating redirects, so bare-path redirect rules like /concepts/:path* never fire. The trailing-slash redirect intercepts first, then /concepts/arbitrage/ doesn't match any redirect → 404. Adds trailing-slash source variants for all exact-match redirects and section index paths. Also adds redirects for /me and /value-bets which GSC reported as 404s. Fixes 5 GSC redirect errors + ~5 of the 19 GSC 404s. Co-authored-by: paperclip-resolver[bot] <3736210+paperclip-resolver[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c63f3d7 commit a339967

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

vercel.json

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@
55
"cleanUrls": true,
66
"ignoreCommand": "git diff --quiet HEAD^ HEAD -- app/ components/ content/ public/ scripts/ next.config.mjs proxy.ts mdx-components.tsx package.json vercel.json",
77
"redirects": [
8+
{
9+
"source": "/me",
10+
"destination": "/en/",
11+
"permanent": true
12+
},
13+
{
14+
"source": "/me/",
15+
"destination": "/en/",
16+
"permanent": true
17+
},
18+
{
19+
"source": "/value-bets",
20+
"destination": "/en/api-reference/opportunities-ev",
21+
"permanent": true
22+
},
23+
{
24+
"source": "/value-bets/",
25+
"destination": "/en/api-reference/opportunities-ev/",
26+
"permanent": true
27+
},
828
{
929
"source": "/",
1030
"destination": "/en/",
@@ -30,36 +50,71 @@
3050
"destination": "/en/api-reference/odds",
3151
"permanent": true
3252
},
53+
{
54+
"source": "/api/v1/futures/odds/",
55+
"destination": "/en/api-reference/odds/",
56+
"permanent": true
57+
},
3358
{
3459
"source": "/splits",
3560
"destination": "/en/api-reference/splits",
3661
"permanent": true
3762
},
63+
{
64+
"source": "/splits/",
65+
"destination": "/en/api-reference/splits/",
66+
"permanent": true
67+
},
3868
{
3969
"source": "/odds/delta",
4070
"destination": "/en/api-reference/odds-delta",
4171
"permanent": true
4272
},
73+
{
74+
"source": "/odds/delta/",
75+
"destination": "/en/api-reference/odds-delta/",
76+
"permanent": true
77+
},
4378
{
4479
"source": "/odds/best",
4580
"destination": "/en/api-reference/odds-best",
4681
"permanent": true
4782
},
83+
{
84+
"source": "/odds/best/",
85+
"destination": "/en/api-reference/odds-best/",
86+
"permanent": true
87+
},
4888
{
4989
"source": "/odds",
5090
"destination": "/en/api-reference/odds",
5191
"permanent": true
5292
},
93+
{
94+
"source": "/odds/",
95+
"destination": "/en/api-reference/odds/",
96+
"permanent": true
97+
},
5398
{
5499
"source": "/streaming",
55100
"destination": "/en/streaming/overview",
56101
"permanent": true
57102
},
103+
{
104+
"source": "/streaming/",
105+
"destination": "/en/streaming/overview/",
106+
"permanent": true
107+
},
58108
{
59109
"source": "/streaming/overview",
60110
"destination": "/en/streaming/overview",
61111
"permanent": true
62112
},
113+
{
114+
"source": "/streaming/overview/",
115+
"destination": "/en/streaming/overview/",
116+
"permanent": true
117+
},
63118
{
64119
"source": "/streaming/:path*",
65120
"destination": "/en/streaming/:path*",
@@ -70,11 +125,21 @@
70125
"destination": "/en/api-reference/overview",
71126
"permanent": true
72127
},
128+
{
129+
"source": "/api-reference/",
130+
"destination": "/en/api-reference/overview/",
131+
"permanent": true
132+
},
73133
{
74134
"source": "/api-reference/overview",
75135
"destination": "/en/api-reference/overview",
76136
"permanent": true
77137
},
138+
{
139+
"source": "/api-reference/overview/",
140+
"destination": "/en/api-reference/overview/",
141+
"permanent": true
142+
},
78143
{
79144
"source": "/api-reference/:path*",
80145
"destination": "/en/api-reference/:path*",
@@ -85,6 +150,11 @@
85150
"destination": "/en/concepts/arbitrage",
86151
"permanent": true
87152
},
153+
{
154+
"source": "/concepts/",
155+
"destination": "/en/concepts/arbitrage/",
156+
"permanent": true
157+
},
88158
{
89159
"source": "/concepts/:path*",
90160
"destination": "/en/concepts/:path*",
@@ -95,6 +165,11 @@
95165
"destination": "/en/sdks/typescript",
96166
"permanent": true
97167
},
168+
{
169+
"source": "/sdks/",
170+
"destination": "/en/sdks/typescript/",
171+
"permanent": true
172+
},
98173
{
99174
"source": "/sdks/:path*",
100175
"destination": "/en/sdks/:path*",
@@ -105,6 +180,11 @@
105180
"destination": "/en/examples/arbitrage-scanner",
106181
"permanent": true
107182
},
183+
{
184+
"source": "/examples/",
185+
"destination": "/en/examples/arbitrage-scanner/",
186+
"permanent": true
187+
},
108188
{
109189
"source": "/examples/:path*",
110190
"destination": "/en/examples/:path*",
@@ -115,41 +195,81 @@
115195
"destination": "/en/authentication",
116196
"permanent": true
117197
},
198+
{
199+
"source": "/authentication/",
200+
"destination": "/en/authentication/",
201+
"permanent": true
202+
},
118203
{
119204
"source": "/quickstart",
120205
"destination": "/en/quickstart",
121206
"permanent": true
122207
},
208+
{
209+
"source": "/quickstart/",
210+
"destination": "/en/quickstart/",
211+
"permanent": true
212+
},
123213
{
124214
"source": "/pricing",
125215
"destination": "/en/pricing",
126216
"permanent": true
127217
},
218+
{
219+
"source": "/pricing/",
220+
"destination": "/en/pricing/",
221+
"permanent": true
222+
},
128223
{
129224
"source": "/en/streaming",
130225
"destination": "/en/streaming/overview",
131226
"permanent": true
132227
},
228+
{
229+
"source": "/en/streaming/",
230+
"destination": "/en/streaming/overview/",
231+
"permanent": true
232+
},
133233
{
134234
"source": "/en/api-reference",
135235
"destination": "/en/api-reference/overview",
136236
"permanent": true
137237
},
238+
{
239+
"source": "/en/api-reference/",
240+
"destination": "/en/api-reference/overview/",
241+
"permanent": true
242+
},
138243
{
139244
"source": "/en/concepts",
140245
"destination": "/en/concepts/arbitrage",
141246
"permanent": true
142247
},
248+
{
249+
"source": "/en/concepts/",
250+
"destination": "/en/concepts/arbitrage/",
251+
"permanent": true
252+
},
143253
{
144254
"source": "/en/sdks",
145255
"destination": "/en/sdks/typescript",
146256
"permanent": true
147257
},
258+
{
259+
"source": "/en/sdks/",
260+
"destination": "/en/sdks/typescript/",
261+
"permanent": true
262+
},
148263
{
149264
"source": "/en/examples",
150265
"destination": "/en/examples/arbitrage-scanner",
151266
"permanent": true
152267
},
268+
{
269+
"source": "/en/examples/",
270+
"destination": "/en/examples/arbitrage-scanner/",
271+
"permanent": true
272+
},
153273
{
154274
"source": "/en/openapi.json",
155275
"destination": "/openapi.json",

0 commit comments

Comments
 (0)