Skip to content
Twilight React Playground
ثيم رائدaren

earlyHintsMiddleware

middlewareAdvancedserver

Optional request middleware that adds preload Link headers for the SDK, fonts and theme CSS to every HTML response.

import { earlyHintsMiddleware } from '@salla.sa/twilight-theme-engine/tanstack';

In plain words

Before a browser can show a page it downloads scripts, fonts and stylesheets. It can start sooner if the response says what is coming. earlyHintsMiddleware() adds that list to each HTML response as Link headers.

It is an optimisation: a theme works without it. The reference theme lists it after twilightMiddleware() in app/start.ts; this playground does not use it.

Signature

function earlyHintsMiddleware(): AnyRequestMiddleware   // from @tanstack/react-start

Example

app/start.ts
import { createStart } from '@tanstack/react-start';
import { twilightMiddleware, earlyHintsMiddleware } from '@salla.sa/twilight-theme-engine/tanstack';

export const startInstance = createStart(() => ({
  // earlyHintsMiddleware() reads the request context, so it comes after twilightMiddleware().
  requestMiddleware: [twilightMiddleware(), earlyHintsMiddleware()],
}));

How it behaves

  • It waits for the rendered response (await next()), then returns a copy with extra Link headers. A request whose Accept header neither contains text/html nor equals */* passes through untouched.

  • Header sources: first the root head's links for the locale in the path (stylesheets that are not media="print" become rel=preload; as=style, rel=preload links with an as and modulepreload links are kept, preconnects and icons are skipped), then every CSS file of the root route in the TanStack Start manifest, as rel=preload; as=style. The manifest list is computed once per middleware instance.

  • If building the root head throws, it logs [earlyHints] rootHead failed: and sends a fixed list instead: the lit module, plus preconnects to api.salla.dev, cdn.salla.sa, cdn.assets.salla.network and fonts.gstatic.com.

  • It does not send a 103 Early Hints response itself; the engine's comment in src/tanstack/index.ts leaves that step to the platform. What it adds are headers on the final response.

  • The /tanstack entry imports the virtual module tanstack-start-manifest:v for this middleware, so anything imported from @salla.sa/twilight-theme-engine/tanstack loads only inside a TanStack Start build.

Gotchas

  • The locale is read with /^\/([a-z]{2})(\/|$)/. When the first path segment is not a two-letter code, only the manifest CSS is announced: on stores that are not multilingual (no locale in the URL), on the ind locale, and on localhost and the preview host, where the store username comes first (/<username>/ar/cart). Check the headers on a real storefront address, not on localhost.

  • List it after twilightMiddleware(). Listed first, its code after next() runs outside the request context: building the root head throws No request context, and every HTML response logs [earlyHints] rootHead failed and carries only the fixed list.

  • docs/getting-started/04-theme-anatomy.md says it "emits 103 Early Hints". It adds Link headers to the normal response.

Related

Source and docs