Skip to content

SSR Hydration API

The hydration API provides fine-grained control over SSR mismatch detection, abort protocol, and recovery. Most apps only need initRuntime() — the rest is available for advanced use cases.

  1. startHydration() — begin hydration session

  2. loadMangleMapFromDOM() — read the injected checksum mangle map from the <script> tag

  3. verifyMangleChecksum() — validate SHA-256 against data-sz-checksum

  4. If invalidabortHydration() preserves SSR HTML and CSS intact

  5. If valid — React hydrates normally

  6. endHydration() — close session, emit audit log

Opens a hydration session. Call before any validation or React render.

function startHydration(): void;

Closes the current hydration session.

function endHydration(): void;

Aborts hydration. Blocks React from taking over the DOM.

function abortHydration(): void;

Returns true if abortHydration() has been called.

function isHydrationAborted(): boolean;

Returns true if a hydration session is active.

function isHydrating(): boolean;

Reads the injected checksum mangle map from the #__CSSZYX_MANGLE_MAP__ script tag in the DOM. The legacy #__SZ_MANGLE_MAP__ id is still accepted for older builds.

function loadMangleMapFromDOM(): MangleMap | null;
type MangleMap = Record<string, string>; // { 'class:p-4': 'z', 'var:--_sz-p:--cz': '--cz' }

When production.mangleVars or production.mangleGlobalVars emits CSS variable aliases, the checksum payload includes both class and CSS-variable entries. One original dynamic variable can map to more than one mangled name, so one-to-many variable entries are namespaced with the mangled name in the checksum key. Global aliases use the same var: namespace, for example var:--brand-primary.

Compares the expected mangle checksum with the checksum embedded on <html data-sz-checksum="...">. Returns true if they match.

function verifyMangleChecksum(expectedChecksum: string): boolean;

Validates the injected mangle map against the embedded checksum.

function verifyMangleMapIntegrity(): boolean;

Checks that a single mangled class exists in the mangle map.

function validateHydrationClass(mangledClass: string, map: MangleMap): boolean;

Returns all recorded hydration errors for the current session.

function getHydrationErrors(): HydrationError[];
interface HydrationError {
type: HydrationErrorType;
message: string;
class?: string; // The mangled class that failed (if applicable)
timestamp: number;
}

Clears the error list. Useful for testing.

function clearHydrationErrors(): void;
type HydrationErrorType =
| "checksum_mismatch" // SHA-256 does not match
| "missing_manifest" // No mangle map in DOM
| "invalid_manifest" // Mangle map is malformed
| "class_not_found" // Mangled class has no mapping
| "token_invalid"; // Recovery token signature is invalid

Recovery tokens allow trusted mangle maps to be accepted even when the main checksum check fails. Available in development only.

Verifies a recovery token against a mangle map.

function verifyRecoveryToken(token: string, map: MangleMap): VerificationResult;
interface VerificationResult {
valid: boolean;
mode: RecoveryMode;
expiresAt?: number;
}

Returns true if a recovery token is present in the DOM.

function hasRecoveryToken(): boolean;

Returns the current recovery mode.

type RecoveryMode = "none" | "csr" | "dev-only";
function getRecoveryMode(): RecoveryMode;

enableCSRRecovery() / disableCSRRecovery() / isCSRRecoveryAllowed()

Section titled “enableCSRRecovery() / disableCSRRecovery() / isCSRRecoveryAllowed()”

Manually enable or disable client-side recovery.

function enableCSRRecovery(): void;
function disableCSRRecovery(): void;
function isCSRRecoveryAllowed(): boolean;

Returns true when running in an SSR context (no DOM available).

function isSSREnvironment(): boolean;

Returns the current SSR context object.

function getSSRContext(): SSRContext | null;
interface SSRContext {
buildId: string;
checksum: string;
timestamp: number;
hasRecoveryTokens: boolean;
}

Production builds with debug helper injection expose window.__csszyx for inspection. mangleMap stays class-only, while varMangleMap contains CSS variable mappings when production.mangleVars is enabled.

interface CsszyxDebugHelper {
mangleMap: Record<string, string>;
varMangleMap: Record<string, string | string[]>;
checksum: string;
encode(originalClass: string): string | undefined;
decode(mangledClass: string): string | undefined;
encodeVar(originalVar: string): string | string[] | undefined;
decodeVar(mangledVar: string): string[];
}

For advanced control over the hydration process:

import {
startHydration,
endHydration,
abortHydration,
loadMangleMapFromDOM,
verifyMangleChecksum,
isHydrationAborted,
} from "@csszyx/runtime";
// In your app entry before React.hydrate()
startHydration();
const mangleMap = loadMangleMapFromDOM();
const checksum = document.documentElement.dataset.szChecksum;
if (!mangleMap || !checksum || !verifyMangleChecksum(checksum)) {
abortHydration();
}
if (!isHydrationAborted()) {
// Safe to hydrate
hydrateRoot(document.getElementById("root"), <App />);
}
endHydration();