Skip to content

[config] Fix rewrite() and redirect() return types for VercelConfig compatibility#15566

Merged
MatthewStanciu merged 5 commits intovercel:mainfrom
SferaDev:fix/config-rewrite-return-type
Mar 16, 2026
Merged

[config] Fix rewrite() and redirect() return types for VercelConfig compatibility#15566
MatthewStanciu merged 5 commits intovercel:mainfrom
SferaDev:fix/config-rewrite-return-type

Conversation

@SferaDev
Copy link
Copy Markdown
Contributor

@SferaDev SferaDev commented Mar 16, 2026

Summary

  • Narrow the return type of the 2-arg rewrite(source, destination) overload from Rewrite | Route to Rewrite
  • Narrow the return type of the 2-arg redirect(source, destination) overload from Redirect | Route to Redirect
  • Fix the no-transforms code path that incorrectly returned a Route (with src/dest) instead of Rewrite/Redirect (with source/destination) when the destination contained env vars from deploymentEnv()

Bug

Since #15016 made Route.source optional (string | undefined), the union Rewrite | Route is no longer assignable to Rewrite[] in VercelConfig.rewrites, causing a type error on the documented usage pattern:

import { routes, type VercelConfig } from '@vercel/config/v1';

export const config: VercelConfig = {
  rewrites: [
    routes.rewrite('/about', '/about-our-company.html'), // TS2322
  ],
};
image

Type fix

The 2-arg overloads always produce Rewrite / Redirect at runtime, so the return type is narrowed to match. The callback and options overloads retain Rewrite | Route / Redirect | Route.

Runtime fix

When the destination contained env var references (e.g. deploymentEnv('API_HOST')), the no-transforms code path eagerly converted to Route format (regex src/dest). This meant the returned object had src/dest properties instead of the declared source/destination, which would break if passed to convertRewrites() downstream. Since both Rewrite and Redirect already have an env field, we now return the high-level type directly and let convertRewrites/convertRedirects handle regex conversion.

The simple 2-arg `rewrite(source, destination)` and `redirect(source, destination)`
calls always produce `Rewrite` / `Redirect` objects at runtime, but were typed as
returning `Rewrite | Route` / `Redirect | Route`. Since `Route.source` is
`string | undefined` (made optional in vercel#15016) while `Rewrite.source` is `string`,
the union is not assignable to `Rewrite[]` / `Redirect[]` in `VercelConfig`.

Narrow the 2-arg overloads to return `Rewrite` / `Redirect` so the documented
pattern works without type errors:

```ts
export const config: VercelConfig = {
  rewrites: [
    routes.rewrite('/about', '/about-our-company.html'), // no longer errors
  ],
};
```

The callback and options overloads retain `Rewrite | Route` / `Redirect | Route`
since those can legitimately produce `Route` objects with transforms.
@SferaDev SferaDev requested review from a team and MatthewStanciu as code owners March 16, 2026 09:10
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: 99bfa7e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@vercel/config Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 16, 2026

Low Risk — Type narrowing + bug fix in config package; no auth/billing/schema changes.

  • .changeset/unlucky-plums-peel.md: added patch changeset for @vercel/config
  • packages/config/src/router.ts: narrowed return types from Rewrite | Route to Rewrite and Redirect | Route to Redirect; removed env-var code path that returned Route format
  • packages/config/src/router.test.ts: added tests for env var handling in rewrite/redirect

Assessed at 99bfa7e.

Fixes the return types of rewrite() and redirect() to ensure compatibility with VercelConfig.
… destination has env vars

The no-transforms code path was eagerly converting to Route format (regex
src/dest) when the destination contained env vars. Since both Rewrite and
Redirect already have an env field, return the high-level type and let
convertRewrites/convertRedirects handle regex conversion downstream.
Copy link
Copy Markdown
Contributor

@MatthewStanciu MatthewStanciu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, thanks for catching this & submitting a fix! We need a better way to keep these in sync with routing-utils

This reverts commit 80509c4.
@MatthewStanciu MatthewStanciu merged commit f8a179a into vercel:main Mar 16, 2026
48 of 53 checks passed
@SferaDev SferaDev deleted the fix/config-rewrite-return-type branch March 16, 2026 21:39
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.

2 participants