Skip to content

Releases

@solidjs/start@2.2.2

Choose a tag to compare

@github-actions github-actions released this 07 Nov 00:40
903f076

Patch Changes

  • 6833ab1: Show server function calls that send files in the dev toolbar as a Seroval tree. The arguments used to show as one raw string, with the files listed apart. Each file now shows in its place in the arguments, with its name and type.
  • 460117b: Serve the page for a HEAD request when a route file exports both a page and a GET that returns nothing, such as a [...404].tsx. The server threw "did not return a response" and answered 500 instead of rendering the page as it does for GET.

@solidjs/start@2.2.1

Choose a tag to compare

@github-actions github-actions released this 03 Nov 01:05
f331543

Patch Changes

  • 2f009ff: Keep the metadata of files and blobs sent to server functions. A blob arrives as a Blob instead of a File named blob, an empty type stays empty instead of application/octet-stream, and a file keeps its exact name and its lastModified. The server still reads uploads from clients that send only the part index.

@solidjs/start@1.5.1

Choose a tag to compare

@github-actions github-actions released this 03 Nov 01:05
5acceb5

Patch Changes

  • 56f1c91: Keep the metadata of files and blobs sent to server functions. A blob arrives as a Blob instead of a File named blob, an empty type stays empty instead of application/octet-stream, and a file keeps its exact name and its lastModified. The server still reads uploads from clients that send only the part index.

@solidjs/start@2.2.0

Choose a tag to compare

@github-actions github-actions released this 01 Nov 23:31
998ff3a

Minor Changes

  • 876881b: Add serverFunctions.skewProtection. When it is on, a page loaded before a deploy can no longer call the new server's functions with an outdated client. The server answers such a call with 409 instead of running the function, and the page reloads once to load the new version. Each build gets a random ID, or pass { buildId } (such as a commit hash) when several machines build the same deploy. Only applies to production builds, and is off by default.
  • d329369: Let server functions take files and blobs anywhere in their arguments, not only as the only argument. A call like upload(file, { tags }), or one with files in arrays, objects, maps, sets or form data, sends them as parts of multipart form data next to the serialized arguments, and the server function gets them as File values. Calls without files are sent as before.

Patch Changes

  • 6a7a496: Bump seroval and seroval-plugins to 1.7.0.
  • ecc390b: Keep the API route matcher out of the client bundle. It is only used on the server, but the client loaded it with the page routes, which added about 2.5 KB of unused code. Routes that only export an OPTIONS handler are now matched as API routes.
  • e8bd8c0: Keep Vite's default resolve conditions ("module", "browser") in the client environment: since 2.1.0, packages exposing a "browser" export condition (e.g. @sentry/solidstart) resolved to their Node build in the browser. The dev overlay's @jridgewell/trace-mapping is now pre-bundled, as the "browser" condition makes it import a UMD build.
  • 6280546: Resolve the server function filter and the ids of lazily loaded modules against Vite's root instead of the working directory. On Windows a working directory entered through a junction or symlink keeps that path, while Vite (8.2 and later) resolves the root and every module id to the real path. The filter then matched no module, so no "use server" function was compiled: its body shipped in the client bundle, and the build failed with Attempt to import 'server-only' in a client module once one of them imported server-only code such as @solidjs/start/http. The ids of lazily loaded route components matched no client manifest entry either, so their CSS was missing from the server-rendered HTML. Relative patterns in the serverFunctions.filter option now resolve against Vite's root too.

@solidjs/start@1.5.0

Choose a tag to compare

@github-actions github-actions released this 01 Nov 23:56
ef743dc

Minor Changes

  • b97f1ee: Let server functions take files and blobs anywhere in their arguments, not only inside a FormData that is the only argument. A call like upload(file, { tags }), or one with files in arrays, objects, maps, sets or form data, sends them as parts of multipart form data next to the serialized arguments, and the server function gets them as File values. Calls without files are sent as before.

@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.