Skip to content

feat(start): send 103 Early Hints for the client entry assets - #466

Open
lxsmnsyc wants to merge 1 commit into
nextfrom
feat/early-hints
Open

lxsmnsyc wants to merge 1 commit into
nextfrom
feat/early-hints

Conversation

@lxsmnsyc

Copy link
Copy Markdown
Member

Adds start.earlyHints, off by default. A production SSR build sends the client entry's scripts and stylesheets as 103 Early Hints before a page renders, so the browser starts downloading them while the server runs middleware, setup and the render. It is the counterpart of SolidStart's earlyHints.

solid({ start: { earlyHints: true }, ssr: true })

Changes

  • Before the page render, the generated handler builds Link values from the client manifest. They cover the client entry, its static imports (rel=modulepreload), and their stylesheets (rel=preload; as=style). The list is computed once per process.
  • The hints go out after the middleware chain reaches the page render, as in SolidStart. Requests that middleware answers, and server-function calls, get none.
  • handleRequest(request, { earlyHints }) takes a callback that receives the links. The start.node entry and vite preview pass one that calls res.writeEarlyHints(), through a new nodeEarlyHints helper in src/http.ts.
  • Without a callback, the links are added as Link headers on the page response, through the request event's response stub. CDNs such as Cloudflare turn those into 103 responses.
  • A non-function earlyHints option is rejected like the other handleRequest options.
  • resolveClientEntry now shares a clientEntryKey() helper with the hint walk. Its behavior is unchanged.
  • README: a new earlyHints section.

Not included

  • SolidStart also hints the assets of lazy route components as they load during SSR. The plugin has no router, so this PR covers the client entry's graph only.
  • Dev and client mode send no hints.

Testing

  • New early-hints mode in examples/start-ssr/test/run.mjs, 12 assertions. It uses node:http to see the 1xx responses:
    • start.node: a page gets a 103, the hinted entry script is the one the page loads, the hinted stylesheets are the page's, every hinted URL answers 200, the final response has no Link header, and a server-function request gets no hints.
    • server.js (calls handleRequest without a callback): no 103, and the same links arrive as Link headers.
    • vite preview: a page gets a 103.
    • Without the option: no 103 and no Link header.
  • The node (89), preview (50) and prod (77) modes, the examples/start-client suite (70) and vitest run still pass.

🤖 Generated with Claude Code

- New start.earlyHints option, off by default, as SolidStart's earlyHints.
- Before a page renders, the generated handler builds Link values for the
  client entry, its static imports, and their stylesheets from the client
  manifest.
- handleRequest accepts an earlyHints(links) callback. The start.node
  entry and vite preview pass one that sends a real 103.
- Without a callback, the links are added as Link headers on the page.
- New early-hints mode in the start-ssr e2e suite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a08788b

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 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: a08788b

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