# @solidjs/start ## 2.1.0 ### Minor Changes - ad92979: Add `ssr: "data-only"`. The app renders on the client without hydration, as with `ssr: false`, but the server runs the requested page's route `preload`s and streams their query results with the HTML shell, so the client doesn't fetch that data again. ### Patch Changes - 5de5afd: Bump `seroval` and `seroval-plugins` to 1.6.11. - c30a825: Support a full URL in Vite's `base` so assets can be served from a CDN, completing the base URL prefixing from 2.0.3. Entry, stylesheet, modulepreload and serialized manifest paths no longer collapse `https://` into `https:/`, and server functions post to the path the app is mounted at (`server.baseURL`, else Vite's `base` when it is a plain path, else `/`) instead of the asset base. There is no CDN in development: Vite serves the assets itself, including the public directory, under the URL's path, while the app stays at the root. Root-relative links to public files therefore differ between dev and a build; setting the CDN `base` for production builds only avoids that. - 2ff5882: Let a `clientOnly` loader resolve to the component itself, so a named export works without wrapping it in `{ default }`: ```tsx const Chart = clientOnly(() => import("./chart").then(({ Chart }) => Chart)); ``` Destructuring the export inside the loader also lets the bundler leave the module's other exports out of the chunk. - 45bacdb: Stop the dev toolbar's CSS from shipping in production builds. The error boundary statically imports the dev toolbar, whose module imports its stylesheet as a side effect. The toolbar is dead code in production, but the stylesheet survived because the package declared no `sideEffects`, so its styles were bundled into the client CSS. The package now marks only CSS files as having side effects, letting the bundler drop the toolbar and its styles from production output. - 9ce2a5d: Add an `earlyHints` option that sends the page's assets as `103 Early Hints`, so the browser can start downloading them while the server is still rendering. It covers the app's entry assets and the assets of the routes being rendered. On runtimes other than Node, the same hints are added as `Link` headers on the response. Off by default, and only applies to production builds. - 6c9b0c9: Fall back to client rendering when the browser's path or query changes before hydration starts, preventing hydration mismatches and stale server data after early navigation. - a235891: Speed up the server function and lazy transforms. - Modules without `"use server"` are no longer parsed by the server function transform. - The server build no longer parses a module with Babel only to add its lazy id. - Modules with many server functions compile about 4 times faster. - A module with a server function no longer fails to compile when it has an unused `for...of` or `for...in` loop variable, or a chain of unused declarations. - 017001e: Keep the result of a form submitted without JavaScript when its form data is too large for the flash cookie. Browsers silently drop cookies over 4096 bytes, so a large textarea used to make `useSubmission()` come back empty on the page the action redirected to. The form data is now left out of the cookie when it would not fit, the result and error still come through, and a warning is logged on the server. - e0e6f6d: Reload the browser when `entry-server` or the middleware changes in dev. Both are server-only, so Vite had nothing to send the browser and the page kept showing the previously rendered output until it was refreshed by hand. - 6a9fb75: Reload the page once when a route's code fails to load during client-side navigation, such as when a deploy replaced it while the page was open. Before, the navigation ended on an error page until the user refreshed by hand. The page now reloads at the destination and loads the new version. A route that still fails right after the reload shows the error instead of reloading again. This only applies to production builds, and can be turned off with `reloadOnRouteChunkError: false`. - 207cfd2: Make `solid-js` a peer dependency instead of a regular one. When an app's `solid-js` version was outside the range SolidStart asked for, package managers installed a second copy just for SolidStart. The two copies did not share reactive context, so client-side navigation broke with `TypeError: Cannot read properties of null (reading 'push')`. SolidStart now uses the app's `solid-js`, and a version outside the supported range shows up as a peer dependency warning at install time. - eb50f39: Serve pages in SPA mode (`ssr: false`) when a route file exports both a page and an API handler, such as a `[...404].tsx` with a `GET`. The server treated those routes as API-only, so a `GET` that returned nothing gave a 404 for every URL the route matched. - ad92979: Export `getServerFunctionMeta`, `decorateHandler` and `decorateMiddleware` from `@solidjs/start/server` in SPA mode (`ssr: false`), so apps using them build. ## 2.0.6 ### Patch Changes - a4ed2a4: Stop `client-only` from failing the build for lazily imported client components. A module that imported `client-only` and was loaded through `clientOnly(() => import(...))` failed the server build, even though it only ever runs in the browser. The server build resolves every dynamic import to emit its chunk, so it resolved the `client-only` module and rejected it, though that module never runs on the server. `client-only` no longer fails the build. `server-only` is unchanged and still fails a client build. - 048f5a9: Stop a no-JS server function POST from returning a 500 when the body is not a form. A POST to a server function without the client runtime, carrying an empty body or a non-form content type, left a value that is not a `FormData` as the last argument. Building the flash cookie called `.entries()` on it and threw, and the error handler rethrew the same way, so the request failed with a 500. The response is now the normal redirect, and the flash cookie is best effort so it can no longer take down the error path. - 59e7dc7: Make reading server function streams safer and faster. - A malformed chunk after the first one is now logged instead of causing an unhandled promise rejection. On hosts that do not catch unhandled rejections, one bad request could stop the server process. - The stream is cancelled when a chunk cannot be read or parsed. - Chunk headers are now checked strictly, and a server rejects chunks over 64MB that a client sends. - Large payloads that arrive in many small pieces are read in linear time. A 16MB chunk read in 16KB pieces took about 2 seconds and now takes about 30ms. - d34acf5: Require seroval and seroval-plugins 1.6.8 or newer. - d34acf5: Send `Cache-Control: no-store` on server function responses by default. Server function responses, including calls made with GET, carried no `Cache-Control`, so a shared cache configured to store them could serve one caller's result to another. Every response from the server function handler now defaults to `no-store`: results, errors, redirects, no-JS redirects, raw `Response` passthroughs, and the handler's own refusals. A `Cache-Control` the function sets itself, on a returned `Response` or on the event's response headers, is kept as is, and a `304` is never given one. - d34acf5: Reject cross-site server function requests. A `"use server"` function could be invoked from another site with the visitor's cookies, over a GET or a form POST, because the request's origin was not checked. Requests to server functions are now allowed only from the same origin or same site. The check trusts the `Sec-Fetch-Site` header and falls back to comparing `Origin` against the request host, so a page on another site receives a `403` instead of running the function. Same-origin calls, user-initiated navigations, and no-JS form submissions are unaffected. A separate origin that needs to call your backend should use an API route with explicit CORS. - 9d3cbec: Report server functions that cannot work instead of compiling them into broken output. - A `"use server"` function that reads a variable from an enclosing function now fails the build. The function is moved to the top level of its module, so the variable is not in scope when it runs. - The same check covers `this` and `arguments` in an arrow function, `super`, and private class members. - A `"use server"` directive in an object or class method now fails the build. It was ignored before, which shipped the method body and the modules it imports to the browser. - A `"use server"` string that is not the first statement of a module or a function body now logs a warning. It has no effect there. - An export a `"use server"` module cannot serve now logs a warning that names it. These exports are still left out of the client build. - A `"use server"` module can now export an anonymous default function. Both `export default async () => {}` and `export default async function () {}` work. - Server function ids are now built from the names a function is nested under, such as `Page.load`, instead of the order the functions appear in. An id no longer changes when another server function is added to the same file, and two functions that share a name are told apart by the names around them. Production ids stay opaque. - Server functions are now compiled in `.mts` and `.cts` files. - Build errors now point at the full path of the file, not just its name. - d34acf5: Treat a server function request with `Origin: null` and no `Sec-Fetch-Site` as cross-site. Browsers send `Origin: null` from opaque origins, such as sandboxed iframes and some cross-origin redirect chains. When `Sec-Fetch-Site` was absent, the handler skipped the `Origin` comparison for that value and allowed the request. It is now refused with a `403`. Requests that carry neither header, such as those from non-browser clients, are still allowed. - d34acf5: Settle server function values that are still waiting on the stream when its body ends. A seroval body can reference a promise or stream that a later frame settles. If the body ended before that frame arrived, the value stayed pending forever, so a server function awaiting such an argument never answered. A malformed later frame also surfaced as an unhandled rejection. When the body ends or fails, every promise still waiting on it now rejects (with the failure, or with "Server function stream ended unexpectedly.") and every open stream errors. Decoded promises that nobody awaits no longer report unhandled rejections; code that awaits them still sees the rejection. ## 2.0.5 ### Patch Changes - eca4cc4: Only strip a whole `index` segment when mapping route files to paths. Route files whose names merely end in "index", such as `routes/reindex.tsx`, were previously served at `/re` instead of `/reindex`. ## 2.0.4 ### Patch Changes - ac3f321: Parse stack traces in the dev toolbar's error overlay with `error-stack-parser-es/lite` instead of `error-stack-parser`. The lite entry point is a much smaller, ESM-only parser that returns plain frame objects rather than class instances, and it no longer pulls in the `stackframe` package. Errors that carry no stack are now handled as an empty frame list instead of throwing. - ac3f321: Redesign the dev toolbar. The toolbar and its panels share a common set of design tokens, giving them a consistent dark palette, translucent surfaces, and elevation. The server function inspector is now a master-detail split with a persistent call list beside the request/response pane, and the error overlay places the stack frame list beside a code preview that fills the panel. Headers, form data, and URL search params render as aligned key-value tables, the hex viewer gains an offset gutter with the ASCII column aligned per row, and blobs are shown as file cards with their type and size. The seroval body inspector is now an expandable tree with collapsed previews, syntax-colored values, cycle detection, and live promise and stream state, replacing the previous column-based drill-down. Along with the redesign, the toolbar only starts a drag from the toolbar itself rather than from its panels, unhandled promise rejections are captured by the error overlay, the code preview shows more surrounding lines, and a stack frame whose source cannot be loaded now stays listed and reports that its source is unavailable instead of silently rendering nothing. - ac3f321: Use `@jridgewell/trace-mapping` instead of `source-map-js` to resolve original sources in the dev toolbar's error overlay. It decodes mappings lazily, so only the positions actually inspected are resolved, it is significantly smaller in the browser bundle, and it understands indexed source maps. - f619c7f: Pre-bundle the dev toolbar's CommonJS dependencies so it no longer throws on every dev page load - d43ad1b: Update Solid to 1.9.15 to include the latest lazy loading and hydration fixes ## 2.0.3 ### Patch Changes - 91fc972: Prefix production entry scripts, stylesheets, modulepreloads, and serialized manifest paths with Vite's configured base URL. ## 2.0.2 ### Patch Changes - e21fadf: fix potentially incomplete first chunk for chunk readers - d78288f: Declare an explicit `Content-Type: text/plain; charset=utf-8` on seroval-stream server function responses (success and error paths) so intermediaries cannot content-sniff a type onto them ## 2.0.1 ### Patch Changes - fd5e2ae: Delegate `vite preview` to Nitro when its preview plugin is active, including for static builds that intentionally have no server entry. ## 2.0.0 ### Highlights SolidStart v2 is now stable. This release replaces Vinxi with direct use of Vite’s Environment API, providing Solid v1 applications with a simpler Vite 8 and Rolldown-powered foundation, improved compatibility with the Vite ecosystem, and direct integration with deployment plugins. SolidStart v2 requires Node.js 24 or newer and Vite 8. Most SolidStart v1 applications can upgrade by moving their framework configuration from `app.config.ts` to `vite.config.ts` and following the migration guide. - [Read the full SolidStart v2 announcement](https://github.com/solidjs/solid-start/discussions/2281) - [Follow the migration guide](https://docs.solidjs.com/solid-start/v2/migrating-from-v1) - [View the complete changelog](https://github.com/solidjs/solid-start/blob/main/packages/start/CHANGELOG.md) ## 2.0.0-rc.10 ### Minor Changes - 3f2b7a7: The file filter logic used for CSS crawling in development can now be configured with the vite plugin option `css.filter` analog to `serverFunctions.filter`: ```ts solidStart({ css: { filter: { // Exclude all node_modules except "my-dependency" with a flat node_modules layout exclude: "node_modules/!(my-dependency)/**/*", }, }, }); ``` ### Patch Changes - 6581877: Fixed shared chunk css not being server rendered in production (Vite 8 regression). - 37d4488: Migrate the built-in Vite configuration from the deprecated `rollupOptions` alias to `rolldownOptions`. - 3f2b7a7: Fixed css from files with url sensitive characters such as `+` not being server-rendered. ## 2.0.0-rc.9 ### Patch Changes - 8eef552: Remove type-only import remnants from client server-function transforms so they do not retain server-only dependency chains. ## 2.0.0-rc.8 ### Patch Changes - 3573985: Await asynchronous `serverFunctions.onError` handlers before serializing server function errors. Preserve the original error if the handler throws or rejects. ## 2.0.0-rc.7 ### Patch Changes - 87d73e1: chore: bump seroval to v1.6.0 ## 2.0.0-rc.6 ### Minor Changes - bac24b2: Add a `serverFunctions.onError` option naming a module that observes and replaces what a server function threw, before it is serialized into the response ### Patch Changes - 27c2877: Remove leftover debug `console.log` calls from the server functions inspector, which logged on every server function request in dev. - f15724b: Declare `@solidjs/router` as an optional peer dependency constrained to `>=0.16.0 <2.0.0-0`. Router v2 is expected to target Solid v2, so installing it alongside `@solidjs/start` v2 now surfaces a peer warning instead of silently producing an incompatible pairing. The peer is marked optional, so apps that do not use the router are unaffected. - 5c8612f: Apply cookies set on a returned or thrown response during single flight mutations. `redirect(to, { headers: { "Set-Cookie": ... } })` previously only reached the browser: the single flight re-render of the redirect target still ran with the old request cookies, so queries reading that cookie saw stale values. Those cookies are now merged into the request the re-render sees, matching what a browser round trip would have sent. - 83122ed: Reject server function calls when the response is a 5xx without an X-Error header, instead of resolving with the parsed error body ## 2.0.0-rc.5 ### Minor Changes - 4c803e5: Add `serialization.plugins` to configure custom Seroval plugins for server functions. Values Seroval has no built-in support for (Mongo's `ObjectId`, Prisma's `Decimal`, `Temporal`, and other custom classes) previously threw when returned from or passed to a server function. Point the new option at a module whose default export is an array of plugins: ```ts // vite.config.ts solidStart({ serialization: { plugins: "src/seroval-plugins.ts", }, }); ``` ```ts // src/seroval-plugins.ts import { createPlugin } from "@solidjs/start/serialization"; ``` The module is bundled into both the client and the server so both ends of a server function agree on the format, so it must not import server-only code. SolidStart's built-in plugins keep precedence. Only server-function and action payloads are affected; the SSR hydration payload is serialized by `solid-js/web`. Also adds a `@solidjs/start/serialization` entrypoint re-exporting Seroval's `createPlugin`, `OpaqueReference`, and plugin types, so plugin authors stay on the same Seroval version SolidStart serializes with. ### Patch Changes - e117d91: Route module ids now end in the source extension, so ecosystem plugins apply inside `src/routes`. Route files are imported through an id carrying the picked exports in the query (`routes/api.ts?pick=GET`), which left the id ending in the export name. Plugins whose filter is anchored on the file extension (`/\.[cm]?[jt]sx?$/`, the default for `unplugin-auto-import`, `unplugin-macros` and others) silently skipped every route file. The id now ends with a `lang.` marker, the same convention Vue SFCs use for `?vue&type=script&lang.ts`. Chunk filenames are unchanged. - d8f1ea8: Apply the configured `nonce` to the two script tags that were still missing it, so a strict `script-src` CSP no longer needs `unsafe-inline`: - The client-side redirect that streaming mode emits after the shell has already flushed (``) now carries the nonce. - The SPA entry script tag now carries the nonce, matching the SSR entry script. - 27fca88: Fix actions returning `json()` or `reload()` leaving no-JS form submissions stranded on the `/_server` endpoint. These responses carry a value rather than a destination, so the redirect issued for progressive-enhancement submissions had no `Location` header. It now falls back to the submitting page, and the response value is unwrapped into the flash cookie so `useSubmission().result` matches the JS path. - 75debc3: Scope the built-in `~` alias to the app package, so files in other workspace packages can map `~` to their own root through an importer-aware plugin such as `vite-tsconfig-paths`. In stylesheets and asset URLs (CSS `@import`, `url()`, `new URL(..., import.meta.url)`) `~` still always means the app root, since Vite resolves those without running plugins. ## 2.0.0-rc.4 ### Patch Changes - b6dfaac: Updated dependencies, including `cookie-es` to 3, `shiki` to 4, `srvx` to 0.12.4, `oxc-parser` to 0.141 and `seroval` to 1.5.6. `parseSetCookie` now returns `undefined` for cookies with a forbidden name or an empty name and value, and those cookies are no longer forwarded to nested server function requests. - 02cd41e: Stop the dev toolbar from reporting benign `ResizeObserver loop` notifications as application errors. Browsers dispatch these as window `error` events carrying no error object, so the toolbar was capturing the raw `ErrorEvent` and force-opening the error panel over the app on every resize. - d3c2af2: Don't send server error stack traces to the client in production builds. When a server function throws, the error is serialized and rethrown on the client, and seroval included `Error.prototype.stack` by default, leaking server file paths and internal function names. Stacks are still serialized in development. ## 2.0.0-rc.3 ### Patch Changes - d9018d6: fix(types): add missing properties to `SolidStartOptions` and expose them via Vite plugin configuration - e26cef0: Fix TS2883/TS2742 when emitting declarations for `entry-server.tsx`. `createHandler` now returns `StartHandler`, a type owned by `@solidjs/start`, instead of h3's `H3`, so the inferred type of `export default createHandler(...)` no longer has to be named through a nested `node_modules/@solidjs/start/node_modules/h3` path. - 7c8dbe6: keep TypeScript namespace members in route files during production builds - b3c7aaf: Update `h3` to `2.0.1-rc.26`. - b3c7aaf: Fixed event response status and headers set during server-side rendering with deferred async resources, not being applied on the outgoing response. ## 2.0.0-rc.2 ### Minor Changes - eeff49a: add new dev toolbar ### Patch Changes - bd8cb01: Update srvx to version 0.12.0. - 4e98ac0: Restore the optional `routerLoad` third argument to `createHandler`, which primes custom routers (e.g. TanStack Router) on the server before SSR rendering. It was accidentally dropped in the v2 rewrite. ## 2.0.0-rc.1 ### Minor Changes - 02e561e: Expose experimental `decorateHandler` and `decorateMiddleware` helpers from `@solidjs/start/server` for providing Solid's request context to custom h3 handlers and middleware. ### Patch Changes - f66b5a9: fix: keep non-picked route exports that picked exports reference instead of deleting their bindings, so API handlers can call helpers exported from the same file (#2100); also fixes picked exports declared via `export { ... }` specifiers being dropped (#1659) - 1763296: fix: run `onBeforeResponse` middleware in declared order (#2131) Applications that reversed their `onBeforeResponse` arrays as a workaround should restore the intended declaration order. - cd98e7d: Fix API route matching when `server.baseURL` is configured. ## 2.0.0-beta.10 ### Patch Changes - 8af6304: Support for Vite 8.1 Experimental Bundled Dev Mode - 9d91484: fix: don't crash when a server function throws an error whose message contains non-latin1 characters. - 068b64c: Return a cancellation-safe web `ReadableStream` for streaming SSR in development. Returning Solid's raw stream only rendered on Node; Bun and Deno coerced it to `[object Object]`. ## 2.0.0-beta.9 ### Minor Changes - f3e84ec: Add support for `server-only` and `client-only` modules ### Patch Changes - a8a2328: fix: mark `@solidjs/start/http` and `@solidjs/start/middleware` as `server-only` so importing them from client-reachable code fails loudly at dev/build time, instead of silently shipping them to the browser where they crashed hydration and broke unrelated actions/forms with no diagnostic (#2068) ## 2.0.0-beta.8 ### Patch Changes - ecc02be: fix: resolve server functions in dev when their route was reached through client-side navigation before its module was evaluated on the server - 85b24b2: Use per-environment Vite plugin hook APIs for forward compatibility with Vite 9. ## 2.0.0-beta.7 ### Patch Changes - d2f0621: Support JavaScript projects whose app and client/server entries use `.jsx`. ## 2.0.0-beta.6 ### Patch Changes - 25769f2: Fix Vite preview for non-HTML responses and projects whose server build uses an `.mjs` entry. ## 2.0.0-beta.5 ### Patch Changes - eb73dd5: Use `oxc-parser` to analyze filesystem route exports. ## 2.0.0-beta.4 ### Patch Changes - 21fdb2c: Update `h3` to `2.0.1-rc.25`. ## 2.0.0-beta.3 ### Patch Changes - 12dc2d3: Bundle `h3` and `cookie-es` into server builds to avoid resolving incompatible hoisted versions ## 2.0.0-beta.2 ### Patch Changes - 3e961e0: Require Vite 8 - 11907a2: Fix published package missing `dist/`: pnpm 11 respects `.gitignore` when packing a package without a `files` field, so `2.0.0-beta.1` was published without its build output. Add an explicit `files` field. ## 2.0.0-beta.1 ### Patch Changes - ee1193a: Update srvx to maintain response compatibility with Nitro v3. - e263338: Fix `ERR_UNSUPPORTED_ESM_URL_SCHEME` when running `vite preview` on Windows ## 2.0.0-beta.0 ### Minor Changes - 0a9fdc3: fix cloudflare ### Patch Changes - 0c95804: Fix URL to path conversion in manifest resolver - 6011e5a: Fixed changes in route files resulting in a reload instead of hot module replace. Reloads now only are triggered when adding or removing routes. - 8fb81e6: Fixed niche edge cases in the server functions dead code removal (DCE) logic: - Server functions only referenced in event handlers (e.g. `onClick`) now aren't considered unused and work properly. - Unused variables in server functions no longer lead to compilation errors. - 8d12d6a: Fixed tailwind class changes not getting applied via HMR in filesystem routes. - ec1b82b: Included Vite 8 in the peer dependency range. ## 2.0.0-alpha.3 ### Minor Changes - 798b285: Updated dependencies. - f6f0452: seroval json mode - d4be1b6: Add new directives plugin with shorter function IDs and inner declaration support - b9c4ade: feat: add `env:*` runtime environment variables support ### Patch Changes - ff9607c: import DevEnvironment and Rollup as type from vite - 6da636b: The server function directives runtime is now internally accessed via package.json exports instead of relative paths, fixing inconsistencies in the file resolution. Also the server functions file inclusion/exclusion patterns can now be configured in the start plugin options via `serverFunctions`. - 2885905: fix: clone request headers in single-flight to avoid mutating immutable headers - abe3979: reload ssr server when new route files are created in dev - 7c288f6: Sanitize Location header value in streaming redirect script - 6c83886: update seroval to 1.5.4 - 9d5d783: Add support for Vite 8 asset manifest loading ## 2.0.0-alpha.2 ### Minor Changes - 10bf932: Fix path resolution on Windows - 40d5a27: fix onBeforeResponse - 9201e71: fix text/html missing when ssr is false - a9cd2cc: add `vite preview` support ### Patch Changes - 7077a49: Fixed CSS from shared chunks not being collected via the chunk name. - a620eeb: Fixed virtual module CSS not being collected in vite dev. ## 2.0.0-alpha.1 ### Patch Changes - 8256190: Rework `@solidjs/start/env` - 6cbba24: Fix multiple Set-Cookie headers being lost on redirect responses - d4cc548: ## Bump Seroval - version `1.4.1` - dd40610: Handle base url in api routes - 0c8a5e2: export server types from /server