Speculation Rules
Speculation Rules (W3C draft) are the modern replacement for / . The browser reads a JSON document declaring patterns of links the operator wants speculatively loaded under varying eagerness levels (immediate, eager, moderate, conservative) and pre-fetches or pre-renders matching anchors as the user hovers / scrolls / dwells.
Two emit modes:
1. Speculation-Rules response header — points at a JSON document the operator serves elsewhere (typical for shared rules across many pages):
Speculation-Rules: "/rules/speculation.json"
The header form is the framework's default because it keeps HTML response bodies clean, lets the rules document be cached independently, and avoids touching response bodies (zero risk of body-parse / encoding mishaps).
2. Inline injection — for operators who want per-page rules, the framework can inject the JSON into text/html responses just before (or, falling back, before the first tag). Opt in with { inline: true }.
Mount AFTER securityHeaders and (when used) cspNonce. When inline: true is set, an operator-supplied nonce on req (via cspNonce) is added to the injected tag so a strict CSP allows the rules to load.
app.use(b.middleware.requestId()); app.use(b.middleware.securityHeaders()); app.use(b.middleware.cspNonce({ always: true })); app.use(b.middleware.speculationRules({ rules: { prerender: [ { where: { href_matches: "/articles/*" }, eagerness: "moderate" }, ], prefetch: [ { where: { href_matches: "/api/*" }, eagerness: "conservative" }, ], }, }));
Both mode shapes validate the rules object at construct time so typos surface at boot, never as a silently-ignored speculation rule three deploys later.
b.middleware.speculationRules(req, res, next) #
{ { rules: object, // { prerender: [...], prefetch: [...] } rulesUrl: string, // header-mode URL (alternative to rules) inline: boolean, // default false; injecttag intotext/htmlresponse bodies just before(or fallback before). WhencspNoncemiddleware has populatedreq.cspNonce, the injectedcarries that nonce so strict CSP allows it.The rules object is validated at construct time. Empty / malformed rules throw with a message naming the offending key.
var b = require("@blamejs/core"); var app = b.router.create(); app.use(b.middleware.speculationRules({ rules: { prerender: [ { where: { href_matches: "/articles/*" }, eagerness: "moderate" }, ], prefetch: [ { where: { href_matches: "/api/*" }, eagerness: "conservative" }, ], }, }));Last updated 2026-08-08T16:39:49.652Z by seeder.