Skip to content

feat: version 3 - #15497

Draft
teemingc wants to merge 759 commits into
mainfrom
version-3
Draft

feat: version 3#15497
teemingc wants to merge 759 commits into
mainfrom
version-3

Conversation

@teemingc

@teemingc teemingc commented Mar 5, 2026

Copy link
Copy Markdown
Member

Opened just so that I could easily see CI checks

You can try SvelteKit 3 by installing any of the packages following #15497 (comment) or the ones published with the next tag https://npmx.dev/package/@sveltejs/kit


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

@changeset-bot

changeset-bot Bot commented Mar 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03f1687

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

This PR includes changesets to release 5 packages
Name Type
@sveltejs/kit Major
@sveltejs/adapter-node Major
@sveltejs/adapter-cloudflare Major
@sveltejs/adapter-vercel Major
@sveltejs/adapter-netlify Major

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

@svelte-docs-bot

Copy link
Copy Markdown

@teemingc teemingc added needs-platform-tests This PR needs to run platform tests in order to merge. needs-ecosystem-ci This PR needs to have an ecosystem CI run started prior to its last commit before merging. breaking change labels Mar 5, 2026
@Rich-Harris

Copy link
Copy Markdown
Member

ok, bringing this up to date with main after #15934 etc is proving to be a bit of a PITA but we're getting there. (Unfortunately it also creates conflicts on #15574 — gah.) Logging off now, will pick it up tomorrow. We are at least able to delete quite a bit of stuff now

Comment thread .changeset/shaggy-walls-wave.md Outdated
Comment thread .changeset/tidy-toes-sort.md Outdated
@Rich-Harris Rich-Harris removed the needs-ecosystem-ci This PR needs to have an ecosystem CI run started prior to its last commit before merging. label Jun 4, 2026
@Rich-Harris

Copy link
Copy Markdown
Member

Finally it looks like we have a clean run and can go back to opening PRs against this branch. Will see how much work is involved in fixing the conflicts on #15574

Comment thread packages/kit/src/utils/url.js Fixed
@pkg-svelte-dev

pkg-svelte-dev Bot commented Jul 1, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 03f1687:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/03f1687fe612ce3d2d9131139b5b188d9cf90c64

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

Comment thread packages/kit/src/exports/url.js Fixed
@sveltejs sveltejs deleted a comment from netlify Bot Jul 6, 2026
@teemingc teemingc added needs-platform-tests This PR needs to run platform tests in order to merge. and removed needs-platform-tests This PR needs to run platform tests in order to merge. labels Jul 7, 2026
…uteId` (#16580)

Closes #14847. #15027 fixed the `Path` half of that issue; the `RouteId`
union still lists every directory, so `resolve('/a')` type-checks when
`/a` only holds child routes.

`LayoutParams` now keys off the generated layout map instead of
`RouteId`, and a layout sitting in a directory that isn't a route stops
claiming its own id in `LayoutRouteId`.

`resolve('/')` stops type-checking in an app whose root page lives in a
group, since `/(app)` is the route that serves `/`. Write `resolve('')`
instead.

#16588 covers the `$app/manifest` side. Also points #16588's `routes`
filter at `is_app_route` so the two stay in sync, and rewords its
changeset to cover the #5793 fix.

---------

Co-authored-by: Elliott Johnson <hello@ell.iott.dev>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
kit-basic Ready Ready Preview Jul 31, 2026 2:24pm

Nic-Polumeyv and others added 7 commits August 1, 2026 05:21
…6499)

These two copies have to stay in sync, so build the hash in one place.

Co-authored-by: Rich Harris <rich.harris@vercel.com>
Based on #16580. Adds a few goodies:

- `PageRouteId` and `EndpointRouteId`, which combine to make up
`RouteId` — these make the internal types a bit cleaner and allow you to
discriminate between which routes do what if needed
- `page` and `endpoint` booleans on each entry in
`$app/manifest.routes`, allowing routes to be filtered by capability;
routes containing both `+page` and `+server` have both set to `true`
- A `ManifestRoute` discriminated union that narrows `id` to the
corresponding page-only, endpoint-only, or combined route IDs
- A private `LayoutParamsId` alias for the IDs accepted by
`LayoutParams`, which now correspond specifically to directories
containing layouts
- More accurate layout load types: a colocated endpoint-only route is no
longer included in a layout’s possible `event.route.id` values, since
endpoint requests do not execute layouts

Layouts only run for page routes, not endpoints. Previously, a directory
with both `+layout` and `+server` incorrectly included its endpoint-only
ID in the layout’s possible `event.route.id` type, even though that
value can never occur at runtime. The change restricts it to page IDs
that can actually execute the layout.

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
closes #16616

Not sure if the changeset should be a major. Decided on patch since it
doesn't actually break anything user-facing for `@sveltejs/enhanced-img`
leftover from #15430

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

### Edits

- [x] Please ensure that 'Allow edits from maintainers' is checked. PRs
without this option may be closed.

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Now that Cloudflare has [updated the versions of Node in their build
images](cloudflare/cloudflare-docs#32430), we
can bump Kit's requirement which allows us to make a small tidy-up.

Don't know if there's any benefit to bumping it further — if there is,
now would be a good time to do so
Promised `read()` results held the whole file in memory instead of
streaming it. `ReadableStream.from` exists everywhere the server runtime
ships (Node 20.6+, workerd, Deno, Vercel edge).

Partial reads of a 100MB file drop from 82MB of memory to basically
nothing, huge win.

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
…16626)

Same as the one that was [fixed in the Vercel
adapter](#16077) but not in the
static adapter
ottomated and others added 27 commits August 27, 2026 16:58
We want `SSRManifest` to be an internal implementation detail rather
than a public type that has to remain stable. #16875 removes all adapter
uses of `SSRManifest`, this PR moves it to `internal.d.ts`.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.


---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
Fixes two pre-existing async e2e flakes exposed by the CI run for
#16892.

The form reconnect test previously polled a server-side iterator cleanup
counter. The failed traces show that the form response succeeded and the
targeted `get_count` connection restarted, but transport cleanup had not
updated the counter within the assertion window. Assert the observable
reconnect requests directly instead, including that `get_finite_count`
is not reconnected.

The serial batch tests also retained module-level todo mutations across
retries. Reset the todos before asserting the baseline state so reruns
are idempotent.

Failed workflow:
https://github.com/sveltejs/kit/actions/runs/32541364509

Verification:
- primary test: 100 dev repetitions and 100 build repetitions
- batch mutation sequence: 40 tests
- relevant dev tests with two workers: 120 tests
- relevant build tests: 60 tests
- `pnpm -F test-async check`
- formatting and diff checks

Co-authored-by: svelte-triage-bot <team@svelte.com>
This adds zero-config deployment support for
[Render](https://render.com/) to `adapter-auto`.

Render exposes `RENDER` in the build environment and uses `adapter-node`
for its [SvelteKit
template](https://github.com/render-examples/sveltekit/blob/main/svelte.config.js).
This PR adds a Render detection mapping to `adapter-node`.

I've also updated the `Zero-config deployments` docs to list Render as a
supported environment.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

### Edits

- [x] Please ensure that 'Allow edits from maintainers' is checked. PRs
without this option may be closed.

---------

Co-authored-by: Rich Harris <hello@rich-harris.dev>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Now that #16876 makes `SSRManifest` an internal type, we can remove the
`_` property and rename everything to snake_case. No changeset because
no user impact.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [ ] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
…ault only until edited (#16939)

Since #16331 moved coercion into `coerce_form_value`, `handle_input` has
stored the raw string of every typed value: `fields.value()` reported
`'20'` while typing and `200` after a reset, and an emptied number field
held `''` instead of `undefined`. Typed values are coerced again, the
same way the submitter path already is.

That re-exposes #15937: the default passed to `.as(type, default)` was
re-applied whenever the field's value became `undefined` or `null`, so
an emptied number input, or one cleared with `set()`, snapped back to
its default. The default now only applies until the field is dirty.
`defaultValue` and `defaultChecked` are unchanged, so reset still
restores it. `dirty` is the modified signal from #16208; `touched` would
drop the default on a tab-through. It is client-only, so SSR and a
failed no-JS submission still render defaults. #16237 keys the same rule
on key presence in the model instead. Fixes #15937.
`.as()` in `packages/kit/src/runtime/form-utils.js` is restructured:
data props are assigned directly with `Object.defineProperty` reserved
for the accessors, the FileList is built from one array, the optional
second argument is spelled as `[type, value?: X]` in `AsArgs`, and the
two option guards are one.

The output of `.as()` is unchanged; the new unit test pins it per input
kind including key order. `[type, value?: boolean]` still accepts
`boolean | undefined`, since checkbox fields are optional in the schema,
and `(string & {})` stays on the `string[]` and `radio` branches where a
plain string option has to type-check against a literal union.

In dev, rejecting a field name that is not JS object notation now says
what is expected and links the docs. Improves the error reported in
#14801.

Stacked on #16939.
`create_field_proxy` resolves each field method through one exit, builds
keys and closures only in the branch that uses them, and only clones the
field value in `value()`; `deep_get` returns `undefined` for a path that
runs through a primitive.

Not cloning inside `.as()` means `.as('select multiple').value` is the
live `$state` array rather than a copy; Svelte reads it per option on
every rerun, so reactivity is unchanged, and mutating it from user code
bypasses the `dirty` bookkeeping the same way it always did for `set()`.

In dev, enumerating fields or checking a key with `in` now warns once
and points at `.value()`, since fields are created as they are accessed
and there is nothing to enumerate
(#14647 (comment)).
Closes #14647.

Stacked on #16938.

---------

Co-authored-by: Elliott Johnson <hello@ell.iott.dev>
This enables the cloudflare adapter to emulate the Request.cf property
and later handle websockets responses.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
The docs say to opt fonts into preloading with a `preload` filter but
not what to match against, so what everyone writes is a substring check
against the hashed output path, which silently stops matching when the
font is renamed. #16443 added `filename` for this; this shows it.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets
- [ ] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

### Edits

- [x] Please ensure that 'Allow edits from maintainers' is checked. PRs
without this option may be closed.

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
Vite's `future` flags (`removePluginHookHandleHotUpdate`,
`removeServerHot`, `removePluginHookSsrArgument`) flag three things
kit's dev path still uses: the `handleHotUpdate` hook in the env-vars
plugin, `server.hot.send` in `dev/index.js`, and spreading `resolveId`
`options` in the guard plugin, which enumerates the deprecated `ssr`
getter.

`hotUpdate` also fires for `create`/`delete`, so the manual
`watcher.on('add'|'unlink')` block that existed because
`handleHotUpdate` only covered `change` folds into it. `hot.send` moves
to the client environment, and the guard passes `options` through
unchanged since `skipSelf` already defaults to true.
Let's see if there's any advantage to using the Rust-ified pnpm in CI
https://pnpm.io/blog/releases/12.0

EDIT: ok seems to shave off 3-8 seconds on Node setup depending on the
Node version (24 is faster than 22)
Corrects the import path in the docs snippet
…16960)

`src/runtime`, `src/exports` (minus `exports/vite`) and `src/utils` are
bundled into user apps, but nothing stops them importing `vite`,
`src/core` or `src/exports/vite`. #15953 was exactly that:
`exports/internal/env.js` importing `stackless` from
`exports/vite/utils.js`.

This scopes a `no-restricted-imports` block to those directories. Core
rule, so it runs unchanged under oxlint (#16703).

Fixes #15963
Replaces #16954.

The `popstate` handler in `client.js` awaits route resolution
(`get_navigation_intent`, and again inside `navigate` before `accept`)
before recording that the browser has moved. Under server-side route
resolution that is a network round-trip, during which
`current_history_index` still points at the entry we left. A popstate
arriving in that window is swallowed by the cancellation guard, and a
`goto` pushes an entry with a duplicate `historyIndex`, so later scroll
and snapshot restores read the wrong entry. This is the flake in
https://github.com/sveltejs/kit/actions/runs/33085846048.

Record the traversal synchronously: capture the source entry's scroll
and snapshots and move the indices before anything async, restore them
in `block()` before `history.go(-delta)`, and capture the navigation
token up front so a superseded popstate stops instead of taking over the
newer navigation's token. `navigate` skips its own capture for popped
navigations.

Repro: a 120 ms delay after the `get_navigation_intent` await in the
handler fails `Preserves scroll and focus across popstate...` 4/4 in
`test:server-side-route-resolution:dev` before this change and passes
4/4 after it.
`Query#run` settles a request by resolving the older resolvers in
`#latest` and leaves its own behind, so `#latest` is never empty once a
request has settled. `set()` resolves everything in `#latest` and then
replaces `#promise` unconditionally. When a value arrives through
`set()` while the request is pending, the normal path for single-flight
responses (`remote_request` in `shared.svelte.js`), awaiting consumers
settle twice: through the resolved promise, then again when the new
`#promise` invalidates `#then`. The second settlement runs in a new
batch while the first is still applying, deriveds lose memoization
across the two, and a deep graph downstream of the query recomputes
exponentially (#16854).

`#run()` now removes its own resolver when it settles, so `#latest`
holds exactly the pending requests, and `set()` only replaces `#promise`
when nothing was pending.

Fixes #16854
In `runtime/client/client.js`, `_preload_data` stores every `load_route`
result in `load_cache` and `load_route` hands the entry back whenever
the intent id matches. `navigate` only clears `load_cache` on the commit
path, after `history.pushState`; the redirect branch recurses into
`navigate` for the redirect target and returns before that. So when a
preloaded route redirects and a later hop of the same navigation comes
back to it (a gate: `/dashboard` redirects to `/select` until a flag is
set, `/select` sets it and redirects to `/dashboard`), the cached
redirect is replayed without a fetch on every return until the
20-redirect limit renders the 500 page.

Discard the consumed entry in the redirect branch before recursing,
keyed on `intent.id` so a preload of a different route (such as the
redirect target) survives. The first hop is still served from the
preload; anything after it loads fresh.

Fixes #16484.

Replaces #16930. Thank you for the attempt @bmdavis419, big fan of your
content.

Co-authored-by: Benjamin Davis <davis.benjamin41902@gmail.com>
Cleans up the Vite dev file a bit but most importantly makes the logic
reusable for when we want to use it in analysis and prerendering using a
Vite dev server
Vite 8 exports `parseSync` (oxc, bundled inside rolldown) and deprecates
`parseAst` in its favour: https://vite.dev/guide/migration#advanced. It
parses TS natively, so `@sveltejs/acorn-typescript` goes too.
closes #16914<!-- Add the related issue number here. Repeat this line
for each additional issue it closes -->

<!-- Explain the goal of the PR, why it is needed, and what has been
changed to achieve that goal -->

The fix was trivial, the test was painful to write and requied ai
assistance

- runs in its own file to set DEV to true globally
- has a hand-written svelte component to reproduce the issue

The diff is big because I bumped svelte to latest

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

### Edits

- [x] Please ensure that 'Allow edits from maintainers' is checked. PRs
without this option may be closed.

---------

Co-authored-by: Nic Polumeyv <162764842+Nic-Polumeyv@users.noreply.github.com>
Fixes a pre-existing async live-query test flake observed on
#16944 in CI run
https://github.com/sveltejs/kit/actions/runs/32994679500.

The stats button previously awaited `get_stats()` without first
refreshing its cached query. Cache eviction therefore depended on
`FinalizationRegistry`/GC timing, and CI polling could repeatedly read
the original `cleanup_count` after reconnecting.

Explicitly start a refresh, then await `get_stats()` again. Query
proxies for the same query share the cached resource, so the second
proxy resolves with fresh server state while using the idiomatic
remote-query API.

The follow-up passed async-app type checking, formatting, and diff
validation. A targeted Playwright build also completed, though browser
launch was unavailable in the sandbox because required Chromium system
libraries could not be installed.

---------

Co-authored-by: svelte-triage-bot <team@svelte.com>
…16903)

Fixed #12556

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

### Edits

- [x] Please ensure that 'Allow edits from maintainers' is checked. PRs
without this option may be closed.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Nic Polumeyv <nicolas.polum@outlook.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Nic Polumeyv <162764842+Nic-Polumeyv@users.noreply.github.com>
…6944)

I was today years old when I discovered `<input type="image" />` and how
it works and it got me unreasonably excited. So obviously, I had to try
if it worked correctly with remote functions, and it turns out it
doesn't.

This PR fixes that.

## How it works in HTML

Initially, I thought that `<input type="image" />` was just to show an
image as a submit button, a relic of an era where you couldn't properly
style buttons. But it turns out that it does something much more
interesting. Because when you submit a form with `<input type="image"
/>` two properties are added to the `FormData` (or to the search):
`name.x` and `name.y` with the coordinates of where the pointer was
(inside the image) when it was clicked.

I legit never used it, but I can see how this could sometimes be
necessary, and it would be a shame to lose this progressive enhanced
functionality.

## The fix

The fix works both type wise and runtime wise by allowing the user to
declare `as("image")` when the field is an object with `x` and `y` as
numbers.

A few important notes:

- If it has any other property you can't specify `field.as("image")` as
you would have no way to set the last property
- You can still set `field.x.as("text")` and `field.y.as("text")` so if
by chance you have an `{ x: number; y: number }` schema, but it's not
for an `image` input you can still use them.

Now the kind-of bad news: I think this is a breaking change in case
someone was using `as("image")` on a field which was not `{ x: number;
y: number }`...however this would've error at runtime before (because of
the extra fields) so maybe is acceptable?

P.s. I know AIs love to write in paragraphs, but this was handwritten
lol

---------

Co-authored-by: Nic Polumeyv <nicolas.polum@outlook.com>
Co-authored-by: Nic Polumeyv <nicolas.polum@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…the server runtime (#16967)

`Server` keeps the manifest in `#manifest` and passes it to `respond`,
from where it travels through 16 parameter positions in
`runtime/server`, down to `has_prerendered_path` and
`load_error_components`. The same object is written to
`runtime/server/internal.js` by `set_manifest` in the `Server`
constructor, and `$app/server`'s `read`, `$app/paths`'s `resolve` and
the `read_implementation` branch in `fetch.js` already read it from
there, so `fetch.js` mixed the parameter and the module singleton in one
function.

The parameter is gone and every reader imports `manifest` from
`internal.js`, the same shape #16871 gave `options`. The `Server`
constructor argument and its `set_manifest` call stay. In dev that call
runs per request, so a request in flight during a manifest regeneration
now sees the regenerated manifest, which `read` and `resolve` already
did.

Closes #16519.

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
…kers` (#16754)

Breaking #16705 into smaller pieces; this is the first step of making
the dev environment closer to the workerd runtime. Instead of accessing
Cloudflare bindings on `platform.env`, you would do the following:

```js
import { env } from 'cloudflare:workers';

export function GET({ request }) {
  const value = await env.KV.get('key'); // instead of platform.env
  const userCountry = request.cf.country; // instead of platform.cf
  const cache = caches.open('name'); // instead of platform.caches
}
```

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
…dows (#16972)

`create_function_bundle` traces with `base` set to the filesystem root.
nft treats any absolute-looking string with a dynamic segment as an
asset glob, and the server output has URL strings like

```js
`/${app_dir}/routes${route_id}`   // runtime/pathname.js
```

On Linux this resolves to `/<*>/routes`, the parent directory is `''`,
the stat fails and nothing happens. On Windows it resolves to
`D:\<*>\routes`, the parent `D:` stats fine, and nft runs
`glob('D:/**/*/routes')` over the whole drive, which never finishes once
it hits `pagefile.sys`.

nft also evaluates `process.cwd()` as `base` unless told otherwise, so
`path.join(process.cwd(), 'asset.txt')` was traced from `/` and never
bundled.

nft calls `ignore` with the glob relative to `base` before walking, and
a base-rooted glob is `**\*\routes`. The cwd case has a regression test;
the root-glob case can't fire on Linux for the reason above.

Fixes #16963. Supersedes #16964. Related: vercel/nft#609.
fixes the vite ecosystem ci error
https://github.com/vitejs/vite-ecosystem-ci/actions/runs/32693769091/job/97332021820#step:7:1811

There is no point to us calling `resolve_peer(...)` for a Vite instance
in the `vite/index.js` file anymore since we don't use to run the client
build during a server build (SvelteKit 2 behaviour). Removing this
should avoid the vite-ecosystem-ci error where the Vite runner
`instanceof` check fails from two differently resolved Vite instances
(the one that started the build and the one from our `resolve_peer`).

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…-eval time (#16303)

closes #14286

Dynamic `$app/env` values are normally populated when `Server.init()`
calls `set_env()`. The problem is that `instrumentation.server.js`
deliberately runs before `Server.init()`, so importing `$app/env` there
gives you `undefined`. More subtly, instrumentation can share a chunk
with application code and cause that code to evaluate early too,
permanently capturing those undefined values at module scope.

Basically, instrumentation should run before the application, but not
before the minimum runtime state it is allowed to observe exists.

This adds an environment initializer to `builder.instrument()`. Adapters
provide the final env module location and generate the small
platform-specific initializer; Kit handles the relative import, imports
it before instrumentation, and only then dynamically imports the
application entrypoint. The same ordering now applies in dev and
preview.

The official adapters initialize from their native runtime source:

- Node, Vercel serverless and Netlify serverless use `process.env`
- Cloudflare uses `env` from `cloudflare:workers`
- Netlify edge uses `Deno.env.toObject()`

Added tests for generated import paths, custom facades, module
evaluation order, filename collisions, and a built adapter-node app
reading dynamic env at instrumentation module scope.

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

teemingc and others added 2 commits September 1, 2026 17:41
seeing if this fixes the CI failures on version-3

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
  - Updated project maintenance tooling to a newer patch version.
  - No user-facing changes are included in this release.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
For adapter-cloudflare, we need to add `@cloudflare/vite-plugin` to the
`vite.plugins` array. However, while configuring the plugin, we need
access to `svelte_config.out_dir` in order to tell it how to generate
the `wrangler` config.

This plugin allows adapters to do 
```js
  vite: ({ config }) => ({
    plugins: [
      some_plugin_that_requires(config),
    ]
  }
```

Drive-by, also allows adapters to just specify a `plugins` array if they
don't need to specify `pre` and `post`. This is backwards-compatible.

---

### Please don't delete this checklist! Before submitting the PR, please
make sure you do the following:

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.

### Tests

- [ ] Run the tests with `pnpm test` and lint the project with `pnpm
lint` and `pnpm check`

### Changesets

- [x] If your PR makes a change that should be noted in one or more
packages' changelogs, generate a changeset by running `pnpm changeset`
and following the prompts. Changesets that add features should be
`minor` and those that fix bugs should be `patch`. Please prefix
changeset messages with `feat:`, `fix:`, or `chore:`.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Adapters can now configure Vite plugins dynamically using the
validated SvelteKit configuration.
* Added support for defining adapter Vite plugins as an ordered list or
separate pre/post groups.
  * Expanded public adapter configuration types and documentation.
* **Bug Fixes**
  * Improved handling and ordering of adapter-provided Vite plugins.
* **Documentation**
  * Documented adapter Vite configuration options and plugin ordering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.