Repository navigation
Releases: solidjs/solid-start
Release list
@solidjs/start@2.1.0
Minor Changes
- ad92979: Add
ssr: "data-only". The app renders on the client without hydration, as withssr: false, but the server runs the requested page's routepreloads and streams their query results with the HTML shell, so the client doesn't fetch that data again.
Patch Changes
-
5de5afd: Bump
serovalandseroval-pluginsto 1.6.11. -
c30a825: Support a full URL in Vite's
baseso 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 collapsehttps://intohttps:/, and server functions post to the path the app is mounted at (server.baseURL, else Vite'sbasewhen 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 CDNbasefor production builds only avoids that. -
2ff5882: Let a
clientOnlyloader resolve to the component itself, so a named export works without wrapping it in{ default }: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
earlyHintsoption that sends the page's assets as103 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 asLinkheaders 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...oforfor...inloop variable, or a chain of unused declarations.
- Modules without
-
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-serveror 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-jsa peer dependency instead of a regular one. When an app'ssolid-jsversion 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 withTypeError: Cannot read properties of null (reading 'push'). SolidStart now uses the app'ssolid-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].tsxwith aGET. The server treated those routes as API-only, so aGETthat returned nothing gave a 404 for every URL the route matched. -
ad92979: Export
getServerFunctionMeta,decorateHandleranddecorateMiddlewarefrom@solidjs/start/serverin SPA mode (ssr: false), so apps using them build.
@solidjs/start@1.4.0
Minor Changes
- 0a027ee: Add
ssr: "data-only". The app renders on the client without hydration, as withssr: false, but the server runs the requested page's routepreloads and streams their query results with the HTML shell, so the client doesn't fetch that data again.
Patch Changes
-
92d9603: Let a
clientOnlyloader resolve to the component itself, so a named export works without wrapping it in{ default }: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.
-
8f03760: Add an
earlyHintsoption that sends the page's assets as103 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 asLinkheaders on the response. Off by default, and only applies to production builds. -
e36e23c: Make
event.request.signalabort when the client disconnects on Node. The request was built without a signal tied to the connection, so it never aborted and API routes kept running after the client went away. On web runtimes the platform signal still applies. -
95ca993: 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. -
273496b: Serve pages in SPA mode (
ssr: false) when a route file exports both a page and an API handler, such as a[...404].tsxwith aGET. The server treated those routes as API-only, so aGETthat returned nothing gave a 404 for every URL the route matched.
@solidjs/start@2.0.6
Patch Changes
-
a4ed2a4: Stop
client-onlyfrom failing the build for lazily imported client components.A module that imported
client-onlyand was loaded throughclientOnly(() => 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 theclient-onlymodule and rejected it, though that module never runs on the server.client-onlyno longer fails the build.server-onlyis 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
FormDataas 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-storeon 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 tono-store: results, errors, redirects, no-JS redirects, rawResponsepassthroughs, and the handler's own refusals. ACache-Controlthe function sets itself, on a returnedResponseor on the event's response headers, is kept as is, and a304is 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 theSec-Fetch-Siteheader and falls back to comparingOriginagainst the request host, so a page on another site receives a403instead 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
thisandargumentsin 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. Bothexport default async () => {}andexport 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
.mtsand.ctsfiles. - Build errors now point at the full path of the file, not just its name.
- A
-
d34acf5: Treat a server function request with
Origin: nulland noSec-Fetch-Siteas cross-site.Browsers send
Origin: nullfrom opaque origins, such as sandboxed iframes and some cross-origin redirect chains. WhenSec-Fetch-Sitewas absent, the handler skipped theOrigincomparison for that value and allowed the request. It is now refused with a403. 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.
@solidjs/start@1.3.5
Patch Changes
-
1e7fcf8: Update seroval and seroval-plugins to 1.6.8.
seroval 1.6.8 validates decoded nodes more strictly (a promise cannot settle to another promise, and stream, sequence, and plugin inputs must have the expected shape) and lets
maxBase64Lengthconfigure the 1,000,000-character limit on binary values that 1.5 already enforced. It also enables theTemporalfeature by default. Apps onsolid-js1.9.16 or later share a single seroval copy with@solidjs/start; oldersolid-jsversions pin seroval 1.5 and will install a second copy. -
1e7fcf8: Send
Cache-Control: no-storeon 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 tono-store: results, errors, redirects, no-JS redirects, rawResponsepassthroughs, and the handler's own refusals. ACache-Controlthe function sets itself, on a returnedResponseor on the event's response headers, replaces the default rather than being combined with it, and a304is never given one. -
1e7fcf8: Reject cross-site server function requests with a
403.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. Server function requests are now allowed only from the same origin or the same site. The check trusts theSec-Fetch-Siteheader (cross-siteis refused;same-origin,same-siteandnoneare allowed) and, when it is absent, comparesOriginagainst the request host. AnOrigin: nullwithoutSec-Fetch-Site, as sent by sandboxed iframes and some cross-origin redirect chains, is refused. Requests that carry neither header, such as those from non-browser clients, are still allowed, as are same-origin calls, user-initiated navigations, and no-JS form submissions. A separate origin that needs to call your backend should use an API route with explicit CORS. -
1e7fcf8: Reject server function argument values that are still pending when the request body ends.
A seroval request body can describe a promise or stream that it never settles. Such a value stayed pending forever, so a server function awaiting that argument never answered. Arguments are now decoded with seroval's cross-reference decoder, and once the body has been decoded every promise it left pending rejects with "Server function stream ended unexpectedly." and every stream it left open errors. Arguments the client serializes normally (promises, errors, async iterators, streams,
FormData,Request,Headers,URLand the other supported values) decode as before. Decoded promises that nobody awaits no longer report unhandled rejections; code that awaits them still sees the rejection.
@solidjs/start@2.0.5
Patch Changes
- eca4cc4: Only strip a whole
indexsegment when mapping route files to paths. Route files whose names merely end in "index", such asroutes/reindex.tsx, were previously served at/reinstead of/reindex.
@solidjs/start@2.0.4
Patch Changes
-
ac3f321: Parse stack traces in the dev toolbar's error overlay with
error-stack-parser-es/liteinstead oferror-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 thestackframepackage. 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-mappinginstead ofsource-map-jsto 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
@solidjs/start@2.0.3
Patch Changes
- 91fc972: Prefix production entry scripts, stylesheets, modulepreloads, and serialized manifest paths with Vite's configured base URL.
@solidjs/start@2.0.2
@solidjs/start@2.0.1
Patch Changes
- fd5e2ae: Delegate
vite previewto Nitro when its preview plugin is active, including for static builds that intentionally have no server entry.
@solidjs/start@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.