Skip to content

feat(1.x): add an earlyHints option for 103 Early Hints - #2351

Open
lxsmnsyc wants to merge 1 commit into
1.xfrom
feat/early-hints-1x
Open

lxsmnsyc wants to merge 1 commit into
1.xfrom
feat/early-hints-1x

Conversation

@lxsmnsyc

Copy link
Copy Markdown
Member

Closes #1935 on the 1.x line. Same feature as #2350 on main.

Adds an opt-in earlyHints option to defineConfig. With it on, SolidStart sends the page's assets as 103 Early Hints, so the browser can start downloading them while the server is still rendering.

// app.config.ts
export default defineConfig({ earlyHints: true });

Change

  • New server/early-hints.ts. sendEarlyHints(event, assets) converts the page's <link> assets to Link values: stylesheets as rel=preload; as=style, scripts as rel=modulepreload, with URLs passed through encodeURI.
    • On Node it uses the response's own writeEarlyHints. 1.x requires Node 22, so that is always available.
    • On other runtimes the values are added as Link headers on the response. Those runtimes run on a node-mock-http response whose writeEarlyHints does nothing, so the check is whether the response has a real socket.
    • h3 v1's writeEarlyHints isn't used: it writes a raw HTTP/1.1 103 straight to the socket and has no Link header fallback.
    • It does nothing outside production, with the option off, or once the response headers are sent.
  • 1.x adds route assets in two places during render, so hints are sent from three places:
    • Entry assets: createPageEvent.
    • Route scripts: StartServer, where it collects the matched routes' modulepreload assets.
    • Route stylesheets: lazyRoute's component, which runs on every render. This is guarded by isServer, so it stays out of the client bundle.
  • Off by default, like Nuxt's experimental.writeEarlyHints, because some proxies and clients mishandle 1xx responses.

Testing

Production builds of the 1.x basic fixture, with a route CSS file added to /about, and a raw Node HTTP client that logs each 1xx response and the final one:

Setup Responses for /about
Node, earlyHints: true, stream mode 103 entry CSS + 3 entry JS, 103 about.js, 103 about.css, 200
Node, earlyHints: true, mode: "async" the same three 103s, then 200
Node, option off 200 only
Bun (server.preset: "bun"), earlyHints: true no 103; 200 with a Link header holding all 6 values

The hints match the page's own <link> tags, and the client bundle contains no hint code.

  • New early-hints.spec.ts (6 tests): the Link values, including encoding a non-ASCII URL. Also, writeEarlyHints for a Node response with a socket, Link headers for a response without one, and nothing sent with the option off, outside production, or after the headers are sent.
  • @solidjs/start test:ci (101 tests), typecheck and build pass. apps/tests build, unit:ci and the full Cypress suite against the production build (19) pass.

🤖 Generated with Claude Code

Send the page's assets as 103 Early Hints before the response. On Node
this uses the response's own writeEarlyHints. On other runtimes, which
run on a mock response with no socket, the values are added as Link
headers instead.

- Entry assets are sent from createPageEvent.
- Route scripts are sent from StartServer, where it collects the
  matched routes' modulepreload assets.
- Route stylesheets are sent from lazyRoute's component, which runs on
  every render.
- Nothing is sent once the response headers are out.

Off by default, because some proxies and clients mishandle 1xx
responses. Production builds only.

Closes #1935.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5c04a87

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

This PR includes changesets to release 1 package
Name Type
@solidjs/start 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 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@solidjs/start@2351

commit: 5c04a87

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