Skip to content

Move static redirects out of middleware - #1942

Draft
marcleblanc2 wants to merge 1 commit into
mainfrom
marc/site/redirects-in-next-config
Draft

Move static redirects out of middleware#1942
marcleblanc2 wants to merge 1 commit into
mainfrom
marc/site/redirects-in-next-config

Conversation

@marcleblanc2

Copy link
Copy Markdown
Contributor

What changed

  • next.config.js now gives 732 static redirects to Next.js. Vercel serves these from its routing layer, so a redirect does not invoke a function.
  • Middleware now matches only /v/..., /@..., and /changelog.rss. An ordinary page view no longer invokes the edge middleware or scans the redirects array.
  • A beforeFiles rewrite handles .md requests without middleware.
  • The redirects data is plain CommonJS so both Next config and middleware can load it.

Request handling

Next.js checks a request in this order: headers → redirects → middleware → beforeFiles rewrites → filesystem routes → afterFiles rewrites → dynamic routes → fallback rewrites. Config redirects therefore finish before middleware and are deployed as Vercel routes rather than function code.

The matcher decides which requests can invoke middleware. Narrowing it removes one edge invocation from every ordinary page view while retaining code for version-aware and changelog redirects.

Next automatically prefixes redirect sources and relative destinations with basePath. Production therefore gets /docs; previews do not. The old middleware always added /docs, including on previews.

Redirects remain temporary: permanent: false produces 307, matching NextResponse.redirect. Changing these to permanent 308 redirects is a separate SEO decision.

Route budget and filtering

Vercel permits 2,048 routes per deployment. The data module contains 1,324 rules. Configuration keeps the first duplicate source, matching the old .find, and removes 386 sources containing fragments plus 206 later duplicates. No query-string sources were present. The result is 732 configured redirects (733 in the manifest including Next's built-in base-path redirect).

Fragment sources cannot match because browsers do not send URL fragments to servers. No path-to-regexp-invalid source remained after filtering; next build accepted all 732 routes.

Preview checks

Replace $PREVIEW_URL with the Vercel preview hostname:

curl -sI "$PREVIEW_URL/admin/tls_ssl"
curl -sI "$PREVIEW_URL/admin/config/site-config"
curl -sI "$PREVIEW_URL/admin/config/site-config.md"
curl -sI "$PREVIEW_URL/v/5.0/admin/tls_ssl"
curl -sI "$PREVIEW_URL/@5.0"
curl -sI "$PREVIEW_URL/changelog.rss"

Expect, respectively: 307 to /self-hosted/http-https-configuration; 200 HTML with no x-middleware-* headers; 200 text/markdown; 307 to the 5.0 site with the redirected path; 307 to the 5.0 site root; and 307 to the technical changelog feed.

Task 5c of the Vercel audit tracked in #1905. Note: this PR and the "run checks once" PR both edit next.config.js; whichever merges second needs a trivial rebase.


Replaces #1907 (branch renamed to marc/site/redirects-in-next-config).

@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sourcegraph-docs Error Error Sep 11, 2026 5:25pm UTC

Request Review

marcleblanc2 added a commit that referenced this pull request Sep 11, 2026
## Problem

Vercel's Slack and GitHub posts for a production deploy link "Visit" to
the raw deployment URL, e.g.
`https://sourcegraph-docs-rmeucrf94-sourcegraph-f8c71130.vercel.app/`.
In production `basePath` is `/docs`, so nothing serves `/` and Vercel
returns a 404. People click away thinking the deploy is broken.

| deployment | `/` | `/docs` |
|---|---|---|
| preview | 200 | 404 |
| production | **404** | 200 |

## Change

When `basePath` is set, redirect `/` → `/docs` on the same host
(`basePath: false` so the source matches the bare `/`). Same host, not
`sourcegraph.com/docs`, so the visitor sees the exact deployment in the
post rather than whatever is live. 307 so nothing gets cached if we
change it later.

Preview deployments have no `basePath`, so `redirects()` returns `[]`
and `/` keeps serving the homepage as today.

sourcegraph.com never proxies `/` to Vercel (only `/docs/*`), so the
live site is unaffected.

Also hoisted the duplicated `VERCEL_ENV` ternary into one `basePath`
const so `basePath`, `NEXT_PUBLIC_DOCS_BASE_PATH`, and the redirect
can't drift.

## Verified

`VERCEL_ENV=production npx next dev`:

```
/            307 → /docs
/docs        200
/docs/admin  200
```

Without `VERCEL_ENV`: `/` 200, `/admin` 200, no redirect.

## Note

#1942 also adds a `redirects` key to `next.config.js`; whichever merges
second will need a one-line conflict resolution (keep both entries).

Co-authored-by: Amp <amp@ampcode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant