Skip to content

fix: combine prerendered trailing slash redirects into as few Vercel routes as possible - #17523

Draft
elliott-with-the-longest-name-on-github wants to merge 1 commit into
elliott/vercel-uniform-trailing-slashfrom
elliott/vercel-batched-trailing-slash-redirects
Draft

elliott-with-the-longest-name-on-github wants to merge 1 commit into
elliott/vercel-uniform-trailing-slashfrom
elliott/vercel-batched-trailing-slash-redirects

Conversation

@elliott-with-the-longest-name-on-github

@elliott-with-the-longest-name-on-github elliott-with-the-longest-name-on-github commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #17522, which covers apps where every route uses the same trailingSlash. This PR makes the fallback for everything else (mixed options and 'ignore') much smaller.

Currently the adapter adds two routes per prerendered page. One of them, { src: path, dest: counterpart }, is unnecessary: Vercel strips trailing slashes before it looks up a static file, so /foo/ already finds foo. Worse, because that route doesn't continue, it stops the routes after it from running. For example, prerendered pages skipped the route that sets the skew protection cookie (going by the proxy source; I haven't tested this with skew protection turned on).

The redirects themselves were also buggy:

  • They used Kit's decoded pathnames as regexes. Vercel matches against the raw, percent-encoded path, so a page like /blog/café/ never matched its redirect.
  • Pathnames weren't escaped, so the pattern for /v1.2/ also matched /v1x2/.

What changed

  • The serve routes are gone.
  • The redirects are combined into a few alternation regexes, one set per direction, like ^/(blog/a|blog/b|…)/$ → /$1. A new route starts whenever one gets close to Vercel's 4096-character limit on src. A thousand blog posts now take about 7 routes instead of 2,000.
  • Pathnames are encoded with encodeURI, the same way Kit's prerenderer does it, and regex-escaped. The routes are caseSensitive, matching Kit's router.
  • adapter-static's copy of this code (used when building on Vercel) has the same changes.

There's one small gap left: a client that sends lowercase hex escapes (%c3%a9) won't match a redirect. The page is still served, it just isn't redirected. Browsers send uppercase.

Tests

  • Unit tests cover combining paths, encoding, escaping and splitting at the length limit.
  • basic has new dynamic prerendered routes for both trailing slash modes, with build and platform tests. The redirect test fails on main for the café page.

@elliott-with-the-longest-name-on-github
elliott-with-the-longest-name-on-github added this pull request to stack #17524 October 22, 2026 18:17
@vercel

vercel Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
kit-ts-always Error Error Oct 22, 2026 6:18pm UTC
kit-ts-split Error Error Oct 22, 2026 6:18pm UTC

Request Review

@pkg-svelte-dev

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 0b7b254:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/0b7b25486d1115a4e24bcb5d9e4adac8ab330333

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/17523

@changeset-bot

changeset-bot Bot commented Oct 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0b7b254

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

This PR includes changesets to release 2 packages
Name Type
@sveltejs/adapter-vercel Patch
@sveltejs/adapter-static 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

@elliott-with-the-longest-name-on-github elliott-with-the-longest-name-on-github changed the title fix: combine trailing slash redirects for prerendered pages into as few routes as possible fix: combine prerendered trailing slash redirects into as few Vercel routes as possible Oct 22, 2026
@svelte-docs-bot

Copy link
Copy Markdown

@elliott-with-the-longest-name-on-github elliott-with-the-longest-name-on-github added the needs-platform-tests This PR needs to run platform tests in order to merge. label Oct 22, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-platform-tests This PR needs to run platform tests in order to merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant