Skip to content

feat: allow adapters to pass in Vite plugins#16206

Merged
Rich-Harris merged 9 commits into
version-3from
adapter-vite-plugins
Jul 2, 2026
Merged

feat: allow adapters to pass in Vite plugins#16206
Rich-Harris merged 9 commits into
version-3from
adapter-vite-plugins

Conversation

@teemingc

@teemingc teemingc commented Jul 1, 2026

Copy link
Copy Markdown
Member

Extracts some changes from #15574 that allows adapters to provide their own Vite plugins. If the adapters provide a Vite plugin that configures dev/preview, it's expected for them to fully handle that.

This will allow adapters to change dev/build/preview behaviour that's beneficial regardless of if we adopt the Vite environment API. For example:

  • the Cloudflare adapter could specify the build config platform to target webworkers instead of node
  • adapters can configure the preview server to run the adapter build output with a custom runtime rather than the current behaviour of running the Vite build output in a Node process all the time

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.
    • will probably add some in a follow-up PR. It's more meaningful when done in the adapter packages that actually make use of the change

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 Jul 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 11d981f

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

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit 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

@teemingc teemingc added the feature / enhancement New feature or request label Jul 1, 2026
@teemingc teemingc requested a review from Rich-Harris July 1, 2026 11:49
@teemingc teemingc linked an issue Jul 1, 2026 that may be closed by this pull request
Comment thread packages/kit/src/exports/vite/preview/index.js Outdated
Comment thread packages/kit/src/exports/vite/dev/index.js Outdated
Comment thread .changeset/lazy-tools-bathe.md Outdated
teemingc and others added 3 commits July 1, 2026 19:55
…ator` to `server.respond`, so `event.platform` and platform emulation are lost during `npm run preview`.

This commit fixes the issue reported at packages/kit/src/exports/vite/preview/index.js:240

## Bug

In the refactor of `packages/kit/src/exports/vite/preview/index.js`, two things were removed:

```js
// removed before `return () => {`
const emulator = await svelte_config.kit.adapter?.emulate?.();
```
and the `emulator` property passed to `server.respond(...)` in the SSR middleware.

### Why it's a regression

The PR's stated purpose is only to let adapters provide Vite plugins for the preview server (`adapter_preview`). But in the **common case** where an adapter does *not* provide a preview plugin (`adapter_preview` is `false`), the built-in preview server still runs and handles SSR requests via `server.respond(...)`. With the emulator no longer computed or passed, `event.platform` is never populated during `npm run preview`.

### Concrete trigger

Run `npm run preview` with any adapter that implements `emulate()` (e.g. `adapter-cloudflare`, `adapter-node`, `adapter-vercel`, `adapter-netlify`) and that does *not* register a `configurePreviewServer` Vite plugin. Any `load`/`action`/handler that reads `event.platform` (e.g. `platform.env` bindings on Cloudflare) will now receive `undefined` instead of the emulated platform, whereas it worked in the parent commit.

### Consistency check

The sibling dev server (`packages/kit/src/exports/vite/dev/index.js`) still computes `const emulator = await svelte_config.kit.adapter?.emulate?.();` and passes it to `server.respond`, confirming the preview removal was accidental.

## Fix

Restored the emulator handling in preview:

- Added `Emulator` to the `@sveltejs/kit` `@import` at the top of the file.
- Declared `let emulator` (typed `Emulator | undefined`) alongside `server`/`manifest`.
- Assigned `emulator = await svelte_config.kit.adapter?.emulate?.();` inside the `if (!adapter_preview)` block, since it is only needed when the built-in server handles requests.
- Passed `emulator` back into the `server.respond(...)` options object in the SSR middleware.

This restores platform emulation during `npm run preview` while keeping the new plugin-based preview path (`adapter_preview === true`) unaffected.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: teemingc <[email protected]>
…Error` when an adapter sets `vite` without `plugins`

This commit fixes the issue reported at packages/kit/src/exports/vite/dev/index.js:431

## Bug

In `packages/kit/src/exports/vite/dev/index.js` and `packages/kit/src/exports/vite/preview/index.js`, the code calls `.some(...)` directly on `plugins`:

```js
const adapter_dev = svelte_config.kit.adapter?.vite?.plugins.some(
	(plugin) => plugin.configureServer
);
```

The adapter `vite` option type in `packages/kit/src/exports/public.d.ts` is:

```ts
vite?: {
	...
	plugins?: Plugin[];
};
```

Both `vite` and `plugins` are optional. The optional chaining `?.vite?.plugins` short-circuits only when `adapter` or `vite` is nullish. If an adapter sets `vite` **without** `plugins` (e.g. `vite: {}`), then `plugins` is `undefined` and `.some(...)` is invoked on `undefined`, throwing:

```
TypeError: Cannot read properties of undefined (reading 'some')
```

This crashes dev server startup (`dev/index.js`) and preview startup (`preview/index.js`).

## Fix

Added the missing optional chaining so the call short-circuits when `plugins` is absent:

```js
svelte_config.kit.adapter?.vite?.plugins?.some(...)
```

This matches the safe access pattern already used elsewhere (e.g. `vite/index.js` uses `?.vite?.plugins` with `.filter(Boolean)`).


Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: teemingc <[email protected]>
Comment thread packages/kit/src/exports/vite/preview/index.js Outdated
@svelte-docs-bot

Copy link
Copy Markdown

Comment thread packages/kit/src/exports/vite/dev/index.js Outdated
Comment thread packages/kit/src/exports/vite/index.js Outdated
@pkg-svelte-dev

pkg-svelte-dev Bot commented Jul 2, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 04eee2e:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/04eee2ebfc9935c261dbc00ca87f18c4c03b253c

Open in pkg.svelte.dev: https://pkg.svelte.dev/@sveltejs/kit/c/04eee2ebfc9935c261dbc00ca87f18c4c03b253c

@teemingc

teemingc commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

@Rich-Harris thanks for the review. I've changed it to place the Vite plugins in front and that solves the issue of Kit needing to passthrough request handling (it doesn't need to since it runs last). It also works now when it didn't before because we've already changed our config hooks to run with order: pre. That means they should apply before any normal adapter Vite plugin hooks

@teemingc teemingc requested a review from Rich-Harris July 2, 2026 07:52

@Rich-Harris Rich-Harris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

love this

@Rich-Harris Rich-Harris merged commit 97eb324 into version-3 Jul 2, 2026
17 of 18 checks passed
@Rich-Harris Rich-Harris deleted the adapter-vite-plugins branch July 2, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature / enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adapter api for dev mode support

2 participants