preload
Tells the browser to start downloading a resource it will need soon, without executing it.
preload(href, options)- Added in React 19.0.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$href | string | The URL of the resource you want to download. |
$options | object | Options describing the resource and how to fetch it. |
$options.as | string | Required. The type of resource: audio, document, embed, fetch, font, image, object, script, style, track, video, or worker. |
$options.crossOriginoptional | 'anonymous' | 'use-credentials' | The CORS policy to use. Required when as is "fetch". |
$options.referrerPolicyoptional | string= no-referrer-when-downgrade | The Referer header to send when fetching: no-referrer-when-downgrade (the default), no-referrer, origin, origin-when-cross-origin, or unsafe-url. |
$options.integrityoptional | string | A cryptographic hash of the resource, used to verify its authenticity. |
$options.typeoptional | string | The MIME type of the resource. |
$options.nonceoptional | string | A cryptographic nonce that allows the resource under a strict Content Security Policy. |
$options.fetchPriorityoptional | 'auto' | 'high' | 'low'= auto | Suggests a relative priority for fetching the resource. |
$options.imageSrcSetoptional | string | For use only with as: "image". The source set of the image. |
$options.imageSizesoptional | string | For use only with as: "image". The sizes of the image. |
Return value
voidNothing.
Changelog
- PHP 19.0.0Shipped in the stable react-dom release; previously available only in Canary builds.
preload asks the browser to fetch a resource now and keep it in the cache, without applying or executing it. React emits the corresponding <link rel="preload"> into the document head during client rendering, and into the streamed HTML during server rendering.
When to reach for it
- A font that would otherwise only be discovered after a stylesheet has parsed — the classic cause of a late font swap.
- The hero image or stylesheet of a route the user is about to open: call it on hover or focus of the link, well before the click.
- A resource referenced from JavaScript rather than markup, where the browser's preload scanner cannot find it.
What trips people up
Fonts always need crossOrigin: "anonymous", even same-origin ones. Get that wrong and the browser downloads the file twice and warns that the preload went unused. The same warning appears when the preloaded URL does not exactly match the one later requested — a different query string or a redirect is enough to miss.
This only downloads. A stylesheet fetched this way is not applied and a script is not run; use preinit when you want the resource to take effect. And during server rendering the call is only honoured while a component is rendering: firing it from a module top level or an unrelated callback is silently ignored.
Repeated calls with the same href collapse into one, so calling it on every render is safe.
Example
import { useState } from "react";
import { preload } from "react-dom";
function ProductLink({ product, onOpen }) {
function warmUp() {
preload(product.heroUrl, {
as: "image",
fetchPriority: "high",
imageSrcSet: product.heroSrcSet,
imageSizes: "(max-width: 600px) 100vw, 600px",
});
preload("/styles/product-detail.css", { as: "style" });
}
return (
<li>
<a href={product.href} onMouseEnter={warmUp} onFocus={warmUp} onClick={onOpen}>
{product.name}
</a>
</li>
);
}
export default function Catalogue() {
// Discovered before the stylesheet parses, so the heading never reflows.
preload("/fonts/Inter-Bold.woff2", {
as: "font",
type: "font/woff2",
crossOrigin: "anonymous",
});
const [opened, setOpened] = useState("none");
const products = [
{ name: "Desk lamp", href: "/p/lamp", heroUrl: "/img/lamp-600.avif", heroSrcSet: "/img/lamp-600.avif 600w, /img/lamp-1200.avif 1200w" },
{ name: "Wall clock", href: "/p/clock", heroUrl: "/img/clock-600.avif", heroSrcSet: "/img/clock-600.avif 600w, /img/clock-1200.avif 1200w" },
];
return (
<div>
<h1>Catalogue</h1>
<p>Last opened: {opened}</p>
<ul>
{products.map((product) => (
<ProductLink key={product.name} product={product} onOpen={() => setOpened(product.name)} />
))}
</ul>
</div>
);
}When to use it
- Fetch a webfont during the first render so text does not reflow when the stylesheet finally resolves.
- Start downloading the next page's hero image when the user hovers its link.
- Preload a large background image referenced only from JavaScript, which the preload scanner cannot see.
- Warm the cache for a stylesheet you will apply later with preinit.
Frequently asked questions
Why does the browser say my preloaded resource was not used?
The URL or the request mode did not match the later request. Fonts and as: "fetch" hints need crossOrigin: "anonymous", and the href must match byte for byte — a differing query string or a redirect counts as a different resource.
Does this apply the stylesheet or run the script?
No. It only downloads and caches the resource. Use preinit when you want a stylesheet inserted into the document or a script executed as soon as it arrives.
Can I call it outside of rendering?
In the browser, yes — during render, in an Effect, or in an event handler such as onMouseEnter. During server rendering only calls made while a component renders have any effect; others are ignored.
More examples
Preloading during server rendering
Both calls happen during render, which is the only context the server honours. React hoists them into <link rel="preload"> tags in the head of the streamed document, so the browser starts the avatar and JSON requests while the rest of the HTML is still arriving. Note that as: "fetch" requires crossOrigin — omitting it makes the hint unusable and the request is issued twice.
import { preload } from "react-dom";
function Avatar({ user }) {
// Called while rendering, so the hint is emitted into the streamed HTML.
preload(user.avatarUrl, { as: "image", fetchPriority: "low" });
return <img src={user.avatarUrl} alt="" width={48} height={48} />;
}
export default function TeamPage() {
preload("/api/team.json", { as: "fetch", crossOrigin: "anonymous" });
const team = [
{ id: 1, name: "Ada", avatarUrl: "/img/ada.avif" },
{ id: 2, name: "Grace", avatarUrl: "/img/grace.avif" },
];
return (
<ul>
{team.map((user) => (
<li key={user.id}>
<Avatar user={user} /> {user.name}
</li>
))}
</ul>
);
}Preloading on hover before a route transition
Hovering a nav button issues the two hints; by the time the click lands, the stylesheet and hero image are usually already in the cache, so the transition commits without a flash. Repeated hovers cost nothing because calls with the same href collapse into one. The transition itself is unrelated to preloading — it just keeps the old page visible while the new one prepares.
import { useState, useTransition } from "react";
import { preload } from "react-dom";
const ROUTES = {
reports: { css: "/assets/reports.css", hero: "/img/reports-hero.avif" },
billing: { css: "/assets/billing.css", hero: "/img/billing-hero.avif" },
};
function NavItem({ name, onNavigate }) {
function warm() {
const route = ROUTES[name];
preload(route.css, { as: "style" });
preload(route.hero, { as: "image" });
}
return (
<button onMouseEnter={warm} onFocus={warm} onClick={() => onNavigate(name)}>
{name}
</button>
);
}
export default function Nav() {
const [page, setPage] = useState("reports");
const [isPending, startTransition] = useTransition();
return (
<nav>
{Object.keys(ROUTES).map((name) => (
<NavItem key={name} name={name} onNavigate={(next) => startTransition(() => setPage(next))} />
))}
<p>
Showing: {page} {isPending ? "(loading)" : ""}
</p>
</nav>
);
}
Discussion