Skip to content

feat(server-functions): send the build id header (solid #4215) - #492

Merged
ryansolid merged 2 commits into
nextfrom
claude/project-thread-nj0j7j
Oct 29, 2026
Merged

ryansolid merged 2 commits into
nextfrom
claude/project-thread-nj0j7j

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Requested by Ryan · project thread

solidjs/solid#4215 added an opt-in build check to the server-function runtime: a server configured with buildId answers 409 (unknownFunction: true on the client) to a call whose X-Server-Function-Build header names another build. The client runtime never sends the header. The build integration is meant to add it. Until now, nothing did.

What this does

  • Client build. Every client-environment import of the default runtime resolves to a small wrapper module. The wrapper installs a prepareRequest hook that stamps non-GET calls with the build id. It also re-exports configureServerFunctionsClient, wrapped so that an app's own prepareRequest runs after the stamp instead of replacing it. Core's configureServerFunctionsClient replaces the hook rather than composing it, so without the wrapper an app hook would silently drop the header.
  • Server build. The handler module passes buildId to configureServerFunctionsServer. The id is read from the client build's persisted .vite/solid-server-functions.json, which now carries a buildId field. Reading it from the file instead of the plugin closure keeps the classic two-invocation build consistent, and works when Vite resolves each environment's config separately.
  • GET calls stay bare, as #4215 specified: their identity is the URL (caches, preload matching).
  • Dev is unchanged. A server built without a client build has no id and checks nothing. A custom runtime is left alone, because its configure contract is its own.

Costs and trade-offs

  • Client bytes: about +55 B brotli. This applies only to production apps that use server functions; apps without them pay nothing. It is over the 20 B line, so it needs your call.
  • The id is random per build, like the deployment secret. Every deploy invalidates old tabs' non-GET calls, which reject as unknownFunction (the existing skew signal). The chunk holding the wrapper also gets a new content hash on every build. A content-derived id would make builds reproducible, but it would miss shape changes that come from imported helpers. I chose the safer option.
  • Ordering: the server build must run after the client build. The plugin already needs this for the persisted manifest, and solid:client-build-first enforces it.

Tests

  • New src/server-functions/build-id.test.ts runs a two-invocation build. It checks that the persisted id appears in the client bundle next to the app's hook, and that the server bundle is configured with the same id.
  • I ran the built client bundle against a mocked fetch. The POST carried both X-Server-Function-Build and the app hook's header.
  • examples/start-ssr: 779/779. The byte-identical server.js check now also masks the build id and the client chunk hashes in the baked manifest. ssr, css-matrix, start-client and start-env pass. Unit suite: 74/74.

Generated by Claude Code

…he server

Wires solidjs/solid#4215. The client build sends X-Server-Function-Build on
non-GET calls through a wrapped configureServerFunctionsClient, so an app's
own prepareRequest hook composes with it. The server build reads the id the
client build persisted and passes it as buildId.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117BoWNxauSmmSdFhFbxZip
@ryansolid ryansolid self-assigned this Oct 29, 2026
@changeset-bot

changeset-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ae827a7

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

This PR includes changesets to release 1 package
Name Type
@solidjs/vite-plugin Patch

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

@pkg-pr-new

pkg-pr-new Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@solidjs/vite-plugin@492

commit: ae827a7

@ryansolid
ryansolid merged commit 3fadd1f into next Oct 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants