Key takeaways:
- The Speculation Rules API tells the browser which pages to prefetch or prerender before the visitor clicks, so the next page can open instantly.
- Document rules with an explicit eagerness level let one ruleset cover a whole site. Always set eagerness yourself instead of relying on the defaults.
- Exclude routes that change state, such as cart, logout and account URLs, and delay analytics and ads until a prerendered page is actually shown.
- Support is Chromium-only today. Safari and Firefox ignore the rules safely, so the API works as a progressive enhancement.
- Measure hit rate and waste. A speculation the visitor never uses costs bandwidth, CPU and server load.
Make Uxify one of your go-to sources on Google
Instant loading has become the standard that fast websites are measured against, and it has the attention of online business owners everywhere.
The transition from fast to instant has been in the works for a while, though.
As early as 2009, the quest for faster and more efficient page loading led the Chromium team to create the first resource hints, to which link rel="prerender" was later added.
It was expected to have a significant impact on performance since it involved loading subsequent pages in the background before a user navigates to them, ensuring faster rendering when the transition occurred.
However, this version of prerendering didn’t prove efficient enough and was deprecated in 2017.
Its successor, the Speculation Rules API, takes a far more controlled approach to full prerendering and is what makes truly seamless browsing possible today.
What is Speculation Rules API by Google?
The Speculation Rules API is a JSON-defined API, built by the Chrome team and incubated at the WICG, that improves page loading through speculative loading strategies.
Speculative loading involves predicting and preloading resources for subsequent page navigations, leading to faster rendering times and improved user experiences. The API gives developers a flexible and expressive way to specify which documents should be prefetched or prerendered.
Key details about the Speculation Rules API:
-
Targeting Document URLs: Unlike traditional prefetching mechanisms that target specific resource files, the Speculation Rules API focuses on document URLs. This makes it particularly suitable for multi-page applications (MPAs) rather than single-page applications (SPAs), which should use their framework’s own prefetching instead.
-
Prerendering and Prefetching: The API supports both prerendering and prefetching strategies. Prerendering fetches, renders and loads the page, including its subresources and JavaScript, into an invisible tab, ready for near-instant activation when the user navigates to it. Prefetching downloads only the HTML document of the next page, so the browser still has to fetch its subresources and render it after the click.
-
Browser Support: Covered in detail in Browser support today below. In short, the API works in Chromium-based browsers, and browsers without support simply ignore the rules. You can check support with the following code:
if (
HTMLScriptElement.supports &&
HTMLScriptElement.supports("speculationrules")
) {
console.log("Your browser supports the Speculation Rules API.");
}
-
Alternative to Deprecated Features: It replaces older hints such as
link rel="prefetch"and the deprecated, Chrome-onlylink rel="prerender", offering better performance and a more expressive syntax. -
Consideration for Security: Cross-site prefetches have limitations to protect user privacy. Cross-site prefetching works only if the user has no cookies set for the destination site, preventing potential tracking of user activity.
Why use Speculation Rules API on your website?
The Speculation Rules API enables near-instant page loads for seamless browsing experiences.
Improved page load times, enhanced user satisfaction and potential SEO advantages are compelling reasons for developers to embrace this technology.
By reducing the latency between page navigations, users perceive the website as more fluid and responsive. This shows up in your site’s Core Web Vitals: metrics for a prerendered page are measured from the moment it is activated, so Largest Contentful Paint (LCP) is often close to zero and layout shifts that happened during loading are never seen. Interaction to Next Paint (INP) measures how the page responds to input after it has loaded, so prerendering does little for it.
With instant browsing come lower bounce rates and increased user retention, vital metrics for the success of your online platform. That is the strategic value of integrating the Speculation Rules API.
How does Speculation Rules API work?
The Speculation Rules API is designed to target document URLs rather than specific resource files. It introduces an expressive, configurable syntax for specifying which documents should be prefetched or prerendered.
Rules are written in JSON inside a script type="speculationrules" element, or delivered in a separate file through the Speculation-Rules HTTP header. A ruleset can contain a prefetch array, a prerender array, or both.
There are two kinds of rules:
- List rules name the exact URLs to speculate with
urls. - Document rules let the browser find links on the page itself with
where, matching them by URL pattern or CSS selector.
<script type="speculationrules">
{
"prerender": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/not-safe-to-prerender/*" } }
]
},
"eagerness": "moderate"
}
]
}
</script>
Every rule also has an eagerness level, which decides how early the browser acts on it:
| Eagerness | When Chrome starts the speculation |
|---|---|
immediate | As soon as the rules are parsed. |
eager | On desktop, after the pointer rests on a link for 10ms (since Chrome 143; before that it behaved like immediate). On mobile, since early 2026, 50ms after a link enters the viewport. |
moderate | On desktop, after the pointer rests on a link for 200ms, or on pointer down if that comes first. On mobile, since August 2025, shortly after scrolling stops, for prominent links near where the user last tapped. |
conservative | On pointer or touch down. |
If you leave eagerness out, list rules default to immediate and document rules default to conservative. Always set it explicitly. The defaults differ by rule type, and an explicit value tells the next developer what you intended.
If you’re new to the Speculation Rules API, test the different setups below first, before you manually apply speculative loading to your site.
How to use Google’s Speculation Rules API
The Speculation Rules API allows developers to follow a structured approach to optimizing the prerendering and prefetching processes.
Setup
It starts with creating a script type="speculationrules" element and defining speculation rules in a JSON structure within it.
Speculation rules can be added in either the head or the body of the main frame.
Important: Speculation rules in subframes are not acted upon, and speculation rules in prerendered pages are only acted upon once a user navigates to the page itself.
Speculation rules can be included statically, dynamically, or through an HTTP header.
- Static setup is done in the page’s HTML (perfect for websites where the next action has high certainty, e.g., a news website might want to prerender the highlight for the day)
- Dynamic setup is done via JavaScript (suitable for websites where personalized user experiences are heavily used)
if (
HTMLScriptElement.supports &&
HTMLScriptElement.supports("speculationrules")
) {
const specScript = document.createElement("script");
specScript.type = "speculationrules";
const specRules = {
prerender: [
{
source: "list",
urls: ["/next.html"],
eagerness: "immediate",
},
],
};
specScript.textContent = JSON.stringify(specRules);
document.body.append(specScript);
}
- HTTP header setup is done on the server or CDN (useful when you can’t edit templates). The header points to a JSON file, and the quotes around the path are required:
Speculation-Rules: "/speculationrules.json"
The file must be served with Content-Type: application/speculationrules+json. Relative URLs in it resolve against the JSON file, not the page, unless the rule sets "relative_to": "document". A file on another origin also needs a CORS header such as Access-Control-Allow-Origin.
To inform the browser which URLs to prerender, you can insert JSON instructions onto your pages:
<script type="speculationrules">
{
"prerender": [
{
"source": "list",
"urls": ["next.html", "next2.html"],
"eagerness": "immediate"
}
]
}
</script>
Similarly, insert the following JSON instructions for prefetching:
<script type="speculationrules">
{
"prefetch": [
{
"source": "list",
"urls": ["next.html", "next2.html"],
"eagerness": "immediate"
}
]
}
</script>
It’s possible to add multiple speculation rules to a page, in which case you would instruct the browser on any of the following levels:
- List of URLs
- Multiple
speculationrules - Multiple lists within one set of speculationrules
Rule properties reference
These are the keys a rule can use, with the values Chrome accepts:
| Key | What it does | Example |
|---|---|---|
source | Where URLs come from: "list" or "document". Optional, since urls implies a list rule and where implies a document rule. | "source": "document" |
urls | The exact URLs to speculate. Cannot be combined with where. | "urls": ["/pricing/"] |
where | Conditions tested against every link on the page: href_matches (URL pattern), selector_matches (CSS selector), and and, or, not to combine them. | "where": { "selector_matches": ".product-card a" } |
eagerness | When to start: immediate, eager, moderate or conservative. | "eagerness": "moderate" |
requires | Capabilities the browser must have, or the prefetch is skipped. The only value is "anonymous-client-ip-when-cross-origin", which sends cross-site prefetches through a private proxy. Prefetch only. | "requires": ["anonymous-client-ip-when-cross-origin"] |
referrer_policy | Referrer policy for the speculative request. Cross-site prefetches need one at least as strict as strict-origin-when-cross-origin. | "referrer_policy": "no-referrer" |
relative_to | Resolve URLs against the "document" or the "ruleset" file (the default). Only matters for rules delivered by HTTP header. | "relative_to": "document" |
expects_no_vary_search | Tells the browser which query parameters don’t change the page, so a link with different tracking parameters can reuse the same speculation. The server must also send a matching No-Vary-Search header. | "expects_no_vary_search": "params=(\"utm_source\")" |
tag | A label for the rule or the whole ruleset, sent to your server in the Sec-Speculation-Tags header and shown in DevTools (Chrome 136+). | "tag": "product-prerender" |
target_hint | Lets a prerender serve a link that opens in a new tab: "_self" (default) or "_blank". Prerender only (Chrome 138+). | "target_hint": "_blank" |
Example: speculation rules for an online store
A store’s navigation follows predictable paths: home to category, category to product, product to cart. Rules can follow the same paths and treat each step according to how expensive a wrong guess is.
<script type="speculationrules">
{
"tag": "store-rules",
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/products/*" },
{ "not": { "selector_matches": ".no-speculate" } }
]
},
"eagerness": "moderate"
}
],
"prefetch": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/cart*" } },
{ "not": { "href_matches": "/checkout*" } },
{ "not": { "href_matches": "/account*" } },
{ "not": { "selector_matches": ".no-speculate" } }
]
},
"eagerness": "conservative"
},
{
"where": { "href_matches": "/collections/*" },
"expects_no_vary_search": "params=(\"utm_source\" \"utm_medium\" \"utm_campaign\")",
"eagerness": "moderate"
}
]
}
</script>
What each rule does:
- Product pages are prerendered on hover. Product pages are the most common next step from a category page and the ones where a slow load costs most, so they get the full prerender, but only once the visitor shows intent.
- Everything else is prefetched on click, except cart, checkout and account URLs, which depend on the visitor’s session. Prefetching on pointer down is cheap and still saves a few hundred milliseconds of server time.
- Collection links are prefetched on hover, and the
expects_no_vary_searchhint stops campaign parameters from creating duplicate speculations for the same page. - A
.no-speculateclass gives your team an escape hatch for any individual link without editing the rules.
Adapt the URL patterns to your platform. Shopify uses /products/ and /collections/, while WooCommerce defaults to /product/ and /product-category/.
Specifying routes for prerender/prefetch
Fine-tuning speculative loading involves specifying routes for prerendering and prefetching. By categorizing pages based on their significance or likelihood of user navigation, developers can optimize the speculative loading strategy.
However, there are some routes that are considered unsafe, such as:
- Sign-out URLs;
- Language switching URLs;
- “Add to cart” URLs;
- Sign-in flow URLs where the server calls for an SMS to be sent, e.g., when two-factor authentication (2FA) is needed;
- URLs that initiate server-side ad conversion tracking;
- URLs that trigger a user’s usage limits, for example, by using their monthly free article allowance.
Similar to excluding such pages from caching, the reason for avoiding prefetching and prerendering them is related to dynamic variables.
These are content-sensitive pages where values update based on user actions, and by preloading them in the background, the risk of showing an outdated state of the page is very high.
If the state does change after a speculation has started, for example when the visitor logs in or adds a product to the cart, your server can send Clear-Site-Data: "prefetchCache", "prerenderCache" to throw away speculations that are now stale (Chrome 138+). Shopify sends this header automatically when the cart changes.
Side effects of prerendering
A prerendered page runs its JavaScript in the background, before the visitor has decided to open it. Anything that fires on page load fires during the prerender too, which causes problems for:
- Analytics, which count a page view for a page the visitor may never see.
- Ads, which record an impression nobody saw.
- Personalized or time-sensitive content, such as stock levels, countdowns or a cart count, which can be stale by the time the page is shown.
The fix is to wait until the page is activated. document.prerendering is true while the page is being prerendered, and the prerenderingchange event fires when the visitor navigates to it:
const activated = new Promise((resolve) => {
if (!document.prerendering) return resolve();
document.addEventListener("prerenderingchange", resolve, { once: true });
});
activated.then(() => {
// Start analytics, ad slots and anything time-sensitive here
});
Google Analytics, Google Publisher Tag and Google AdSense already wait for activation by default. Check every other script on the page, especially ones you added yourself.
On the server side, speculative requests carry a Sec-Purpose header: prefetch for a prefetch and prefetch;prerender for a prerender. Use it to keep these requests out of server-side analytics or to skip side effects that should only happen on a real visit.
Chrome also skips or cancels speculations on its own in some situations:
- The visitor has Save-Data turned on.
- Energy Saver is on and the battery is low.
- The device is short on memory.
- The visitor has turned off “Preload pages” in Chrome settings, which some extensions such as uBlock Origin also do.
- The page was opened in a background tab.
Accuracy and trade-offs
As Barry Pollard mentioned in our webinar on “Loading Pages Instantly”:
“[Using prefetching and prerendering] It’s about the balance trying to figure out what you can do to reduce waste efficiency (% of correct predictions) and increase prediction accuracy (# of predictions used).”
While prefetching is the safest approach you can duplicate across many of your web pages, it also offers the lowest reward since it only downloads the HTML document.
Full-page prerenders, on the other hand, offer higher rewards, but they should be used sparingly since they can:
- Overwhelm the browser, as it can only run a limited number of tasks in the background.
- Consume considerable bandwidth and CPU resources, which can lead to performance degradation for users on slower networks or devices with limited resources.
- Lead to higher resource waste if the visitor does not navigate to the page.
We cover how to keep that waste down in minimizing resource waste in speculative preloading.
To set up prerendering properly, you should consider your users’ behavior and analyze common navigations across your website. Using heatmaps and Google Analytics flow charts, you can identify essential routes and start your predictive loading experiments.
To check if a page was prerendered, look for a non-zero activationStart in its PerformanceNavigationTiming entry. You can send that to Google Analytics 4 with the page view:
function pagePrerendered() {
return (
document.prerendering ||
self.performance?.getEntriesByType?.("navigation")[0]?.activationStart > 0
);
}
// Turn off the automatic page view, then send it once the page is shown
gtag("config", "G-XXXXXXXXXX", { send_page_view: false });
activated.then(() => {
gtag("event", "page_view", { prerendered: pagePrerendered() });
});
Google Analytics would delay the page view on its own, but sending it yourself lets you attach the flag. Register prerendered as an event-scoped custom dimension in GA4, and you’ll be able to gauge the ratio between prerendered and other types of navigations.
Additionally, it’s important to measure the number of prerendered pages that are not subsequently visited to optimize speculation rules and achieve higher hit rates and lower resource waste.
You can do this by firing an analytics event when speculation rules are inserted to indicate that a prerender was requested, then comparing the number of these events to the actual prerendered page views. Our guides on how to tell if your speculation rules are working and the KPIs for measuring speculative loading go deeper into both.
Debugging speculation rules in Chrome DevTools
Open Application > Background services > Speculative loads in Chrome DevTools. The panel lists:
- Rules: every ruleset Chrome found on the page, including ones delivered by HTTP header, with any JSON errors.
- Speculations: every URL Chrome decided to prefetch or prerender, its status (not triggered, pending, running, ready or failure) and, for failures, the reason.
To test the effect, disable the cache in the Network panel and throttle the connection to a mobile profile, then click through the same path with and without your rules. On a slow connection, give a moderate prerender a moment to finish before you click. In the opened page, running performance.getEntriesByType("navigation")[0].activationStart in the Console returns a non-zero value if the page was prerendered.
Or you can…
Consider automated page prerendering with Navigation AI
Everything above is work you repeat for every template on your site: picking routes, choosing eagerness, excluding unsafe URLs, and checking hit rates whenever your navigation changes. Navigation AI is the Uxify agent that does that work for you.
Instead of a fixed ruleset, it predicts in real time which page each visitor is most likely to open next, then uses the Speculation Rules API to prerender that page. The click lands on a page that is already painted.
It works in four steps:
- Track behavior. Navigation AI observes real sessions on your site to map the likely next destinations from every page.
- Predict. It combines those journey patterns with live signals from the current visit, such as scroll position, pointer direction and, on mobile, which links are in the viewport, to rank the most likely next pages.
- Prerender. It hands the top candidate to the Speculation Rules API and keeps updating the prediction as the visitor moves around the page. Prerendering the one page a visitor is likely to open, rather than every link, avoids most of the bandwidth and memory waste described above.
- Instant load. When the visitor clicks, the page is already rendered, whatever their device or connection.
It activates on install with no code and no configuration, and runs on Shopify, BigCommerce, Magento, WordPress, Wix, Squarespace and custom-built sites.
Its results compare sessions Navigation AI optimized with sessions it didn’t, on the same site: LCP, TTFB, pages per session and, since August 2026, extra product pages seen per visit. These are observational comparisons rather than A/B tests, and they show what the agent earns in terms a store owner can report on.
Across Uxify customers, Navigation AI predicts the next page correctly 72% of the time, makes navigations 55% faster and lifts pageviews per session by 30%. Two examples:
- Ecigone, a Shopify store with a large catalogue, raised its engaged session rate by 22% and repeat traffic by 9%. On optimized navigations, server response time dropped from 0.4s to 0.01s, because the page was already loaded when the shopper tapped.
- eCommerce Fastlane, a content site running Navigation AI and INProve, grew pageviews per session by 26% and improved LCP by 39% without changing a single article. Rage clicks fell from 3.87% to 1.57%. After about a month of learning, Navigation AI was predicting the next navigation correctly in roughly 65% of cases.
Tuned speculation pays off whoever does the tuning. Ray-Ban’s in-house rollout of speculation rules cut LCP by 43% and doubled mobile conversions, and Google Search reached a similar conclusion with its own: tuned speculation beats simply switching it on. We break that down in how Google Search uses speculation rules.
Speculation Rules API and WordPress
Since WordPress 6.8 (April 2025), speculative loading is part of WordPress core. It is on by default on the front end for logged-out visitors on sites with pretty permalinks, and it prefetches with conservative eagerness, so the next page starts loading when the click begins. WP-admin routes are excluded.
The defaults are deliberately cautious, and developers can change them with the wp_speculation_rules_configuration filter, for example to prerender instead of prefetch or to use moderate eagerness. Returning null from the filter turns the feature off.
The standalone Speculative Loading plugin from the WordPress Core Performance team goes further: it defaults to prerendering with moderate eagerness and adds a settings screen, so you don’t need code to change the behavior.
In our “Instant Page Loading” webinar above, Google’s Developer Relations Engineer Adam Silverstein explains how the WordPress Core Performance team approached bringing the API to the ecosystem.
Speculation Rules API and Shopify
Shopify has applied a platform-wide speculation rules configuration to all Liquid storefronts since June 2025. It is delivered by HTTP header, so it doesn’t appear in your theme code, and it prefetches only.
In May 2026 Shopify reported switching that default from conservative to moderate eagerness. Compared with conservative, speculated navigations on desktop improved at the median by 285ms in TTFB and 228ms in LCP, while mobile gains were small. The cost was nearly 4x more speculated requests on desktop.
Themes can still add their own rules, including prerender rules, on top of the default. See here for details on how to implement the Speculation Rules API in Shopify.
Browser support today
| Browser | Status |
|---|---|
| Chrome, Edge, Opera and other Chromium browsers | Prefetch and prerender supported, on desktop and Android. |
| Safari | WebKit has a prefetch implementation, but it isn’t enabled by default in Safari. Bug fixes to it keep appearing in Safari Technology Preview release notes through 2026. |
| Firefox | Not supported. Mozilla announced in May 2026 that it plans to prototype same-origin prefetch. |
Browsers that don’t support the API ignore the speculationrules script, so adding rules never breaks a page. Visitors on those browsers just get a normal navigation, which makes speculation rules a safe progressive enhancement. For the current picture, check MDN’s compatibility table.
How the Speculation Rules API has changed
The API has grown a lot since its first release. These are the changes that matter most when you write or review rules:
| Change | Version or date | Why it matters |
|---|---|---|
| Document rules and eagerness | Chrome 121–122 (complete in 122) | One ruleset can cover a whole site, and you control how early each rule fires. |
Speculation-Rules HTTP header | Available since 2024 | CDNs and platforms can add rules without editing HTML. |
tag field | Chrome 136 | Lets you tell your own rules apart from a CDN’s or platform’s in server logs and DevTools. |
target_hint | Chrome 138 | Links that open in a new tab can use a prerender. |
Clear-Site-Data cache directives | Chrome 138 | Throw away stale speculations after a login or cart change. |
No-Vary-Search | Chrome 141 | Pages that differ only by tracking parameters share one speculation. |
moderate on mobile | August 2025 | Uses viewport heuristics instead of waiting for a tap, so mobile speculations start earlier. |
eager redefined | Chrome 143 (desktop), early 2026 (mobile) | No longer the same as immediate. It now waits for a short hover or for the link to appear on screen. |
Chrome also has built-in limits on how many speculations run at once, to prevent overuse of resources (both yours and your visitors’):
| Eagerness | Prefetch limit | Prerender limit |
|---|---|---|
immediate | 50 | 10 |
eager, moderate, conservative | 2 (oldest is cancelled first) | 2 (oldest is cancelled first) |
URLs listed with immediate get the higher limit because the browser can’t know which of them the visitor will need. For the hover- and click-based levels, a new speculation cancels the oldest one, which keeps memory use in check.
Prerendering is, by default, confined to same-origin pages. Since Chrome 119 it also works for same-site cross-origin pages, such as shop.example.com from www.example.com, if the target page opts in with the Supports-Loading-Mode: credentialed-prerender header.
What’s next for Speculation Rules
A few changes are still in progress:
-
prerender_until_script, in an origin trial since January 2026, prefetches a page and its subresources and renders it up to the first script. It would bring part of the prerender speed-up with much less risk of side effects. Shopify is evaluating it for storefronts. - Safari and Firefox prefetch. WebKit’s implementation is still being fixed, and Firefox is starting with a same-origin prototype. Prerender support outside Chromium is not announced.
- Cross-origin prerendering is still not supported. Cross-site navigations can only be prefetched, and only under the privacy limits described above.
You can follow the work in the WICG nav-speculation repository, which is where new features are proposed before they ship.
