preinit

Downloads and immediately evaluates a script, or inserts a stylesheet so its rules apply at once.

Signature
preinit(href, options)
  • Added in React 19.0.0

Parameters

ParameterTypeDescription
$hrefstringThe URL of the resource you want to download and execute.
$optionsobjectOptions describing the resource and how to fetch it.
$options.as'script' | 'style'Required. The type of resource.
$options.precedenceoptional'reset' | 'low' | 'medium' | 'high'Required with stylesheets. Says where to insert the stylesheet relative to others; higher precedence can override lower.
$options.crossOriginoptional'anonymous' | 'use-credentials'The CORS policy to use.
$options.integrityoptionalstringA cryptographic hash of the resource, used to verify its authenticity.
$options.nonceoptionalstringA cryptographic nonce that allows the resource under a strict Content Security Policy.
$options.fetchPriorityoptional'auto' | 'high' | 'low'= autoSuggests a relative priority for fetching the resource.

Return value

voidNothing.

Changelog

  • PHP 19.0.0Shipped in the stable react-dom release; previously available only in Canary builds.

preinit goes one step further than a plain download hint: the resource is fetched and put into effect. A script runs as soon as it finishes downloading; a stylesheet is inserted into the document, so its rules apply immediately.

When to reach for it

  • A stylesheet a component owns, declared from the component itself rather than from a global CSS file — React deduplicates it and orders it by precedence.
  • An analytics or feature script you want running as early as possible, without adding a <script> tag by hand.
  • Ahead of a navigation whose target you are certain of, when merely caching the file is not enough because you want it applied on arrival.

What trips people up

The side effect is the point, and it is easy to under-estimate. A script initialized this way executes even if the component that asked for it unmounts a moment later; there is no way to cancel it. If you only want the bytes in the cache, use preload.

precedence is required for stylesheets and is what makes the cascade predictable: React groups inserted stylesheets by precedence, so a sheet at "high" reliably overrides one at "low" no matter which component rendered first. Omitting it gives you insertion-order chaos.

Calls with the same href collapse into one. On the server, only calls made while a component is rendering are honoured.

Example

Example · jsx
import { useState } from "react";
import { preinit } from "react-dom";

function ThemedPanel({ theme, children }) {
  // Inserted into the document and applied right away.
  preinit(`/themes/${theme}.css`, { as: "style", precedence: "high" });
  return <section>{children}</section>;
}

export default function Checkout() {
  const [theme, setTheme] = useState("light");

  // Base rules load at a lower precedence, so the theme above wins.
  preinit("/styles/checkout-base.css", { as: "style", precedence: "low" });

  // Runs as soon as it has downloaded.
  preinit("https://payments.example.com/widget.js", {
    as: "script",
    crossOrigin: "anonymous",
    integrity: "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
  });

  return (
    <ThemedPanel theme={theme}>
      <h1>Checkout</h1>
      <p>Theme: {theme}</p>
      <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
        Switch theme
      </button>
    </ThemedPanel>
  );
}

When to use it

  • Insert a route-specific stylesheet from the component that needs it, ordered by precedence.
  • Start an analytics script during the first render instead of blocking on a script tag.
  • Apply a theme stylesheet the moment a user switches themes.
  • Evaluate a payment widget's script while the checkout form is still rendering.

Frequently asked questions

What is the difference between this and preload?

preload only downloads and caches the resource; preinit also puts it into effect — scripts execute and stylesheets are inserted into the document. Use preload when you want the bytes early but want to decide later whether to apply them.

Why is precedence required for stylesheets?

It tells React where to insert the <link> relative to other inserted stylesheets, which makes the cascade deterministic regardless of the order components render in. Sheets at a higher precedence are placed after — and therefore override — lower ones.

Can I un-initialize a script when the component unmounts?

No. Once the script downloads it executes, and unmounting does not undo it. If the side effect should be conditional, only call the function at the point you are sure you want the script to run.

More examples

Ordering stylesheets with precedence

Overrides renders before DataGrid, so without precedence the vendor sheet would be inserted last and win the cascade. Because React groups inserted stylesheets by precedence, grid-overrides.css is placed after grid.css in the head regardless of render order, and the overrides apply. Only the ordering is guaranteed; specificity still decides between two rules in the same group.

Example · jsx
import { preinit } from "react-dom";

function DataGrid() {
  preinit("/vendor/grid.css", { as: "style", precedence: "low" });
  return <table><tbody><tr><td>Grid body</td></tr></tbody></table>;
}

function Overrides() {
  preinit("/styles/grid-overrides.css", { as: "style", precedence: "high" });
  return null;
}

export default function Report() {
  return (
    <div>
      <h1>Quarterly report</h1>
      <Overrides />
      <DataGrid />
    </div>
  );
}

Initializing a script on a deliberate user action

Deferring the call to a click keeps a heavy third-party script off the critical path and out of the page for users who never open the map. Once clicked the script is fetched and evaluated; clicking again would be a no-op because calls with the same href are deduplicated.

Example · jsx
import { useState } from "react";
import { preinit } from "react-dom";

export default function MapCard() {
  const [ready, setReady] = useState(false);

  function loadMap() {
    // Only run the third-party script once the user has asked for the map.
    preinit("https://maps.example.com/sdk.js", { as: "script" });
    setReady(true);
  }

  return (
    <div>
      <h2>Office location</h2>
      {ready ? (
        <p>Map SDK requested. It will initialize as soon as it downloads.</p>
      ) : (
        <button onClick={loadMap}>Show map</button>
      )}
    </div>
  );
}

Discussion

  • Be the first to comment on this lesson.