Skip to content

Releases: solidjs/solid-start

@solidjs/start@2.1.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 01:51
fbf559d

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 preloads 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 }:

    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.

@solidjs/start@1.4.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 20:22
e2008e2

Minor Changes

  • 0a027ee: 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 preloads and streams their query results with the HTML shell, so the client doesn't fetch that data again.

Patch Changes

  • 92d9603: Let a clientOnly loader 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 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.

  • e36e23c: Make event.request.signal abort 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].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.

@solidjs/start@2.0.6

Choose a tag to compare

@github-actions github-actions released this 07 Oct 21:22
9b943dc

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.

@solidjs/start@1.3.5

Choose a tag to compare

@github-actions github-actions released this 07 Oct 22:15
f4d42c6

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 maxBase64Length configure the 1,000,000-character limit on binary values that 1.5 already enforced. It also enables the Temporal feature by default. Apps on solid-js 1.9.16 or later share a single seroval copy with @solidjs/start; older solid-js versions pin seroval 1.5 and will install a second copy.

  • 1e7fcf8: 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, replaces the default rather than being combined with it, and a 304 is 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 the Sec-Fetch-Site header (cross-site is refused; same-origin, same-site and none are allowed) and, when it is absent, compares Origin against the request host. An Origin: null without Sec-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, URL and 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

Choose a tag to compare

@github-actions github-actions released this 10 Sep 20:37
56197ef

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.

@solidjs/start@2.0.4

Choose a tag to compare

@github-actions github-actions released this 24 Aug 22:30
5d23efb

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

@solidjs/start@2.0.3

Choose a tag to compare

@github-actions github-actions released this 20 Aug 21:22
22f07b8

Patch Changes

  • 91fc972: Prefix production entry scripts, stylesheets, modulepreloads, and serialized manifest paths with Vite's configured base URL.

@solidjs/start@2.0.2

Choose a tag to compare

@github-actions github-actions released this 19 Aug 12:23
97fee2a

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

@solidjs/start@2.0.1

Choose a tag to compare

@github-actions github-actions released this 18 Aug 10:58
af827ad

Patch Changes

  • fd5e2ae: Delegate vite preview to Nitro when its preview plugin is active, including for static builds that intentionally have no server entry.

@solidjs/start@2.0.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 19:47
e0edaa1

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.