InitColorSchemeScript
Set the initial color attribute before React hydration in an SSR document.
This guide covers Material UI Core with the default Emotion engine; extensions and additional demos are explicitly classified.
Use case and business boundary
This is an initialization script, not visible UI; match Provider options, CSP nonce and storage keys, and verify the real server HTML.
Native composition and scope
InitColorSchemeScript
Preserve native Material UI composition and types; do not substitute JGuang UI/Base UI/Radix APIs. Example entries are not extra components.
Native installation and initialization
npm install @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1
Use native npm and Emotion, not an invented JGuang UI Registry URL. Place examples inside native ThemeProvider; choose CssBaseline or ScopedCssBaseline for the project. Inspect React, existing providers, lockfile and SSR first. Never overwrite files or conceal peer conflicts. This batch verified React 19.2.8; React 18 and below require matching react-is. See the included bilingual setup guide.
Practical native parameters
These selected parameters are not a flattened universal API. Preserve the native declaring owner, slot structure, nullable values and generics.
| Owner.prop | Practical role | Declaration source |
|---|---|---|
InitColorSchemeScript.attribute | Initial color selector; match ThemeProvider colorSchemeSelector. | InitColorSchemeScript |
InitColorSchemeScript.defaultMode | Initial native light/dark/system mode when no saved preference exists. | InitColorSchemeScript |
InitColorSchemeScript.modeStorageKey | Native mode preference key; match the Provider and avoid other apps' keys. | InitColorSchemeScript |
InitColorSchemeScript.nonce | CSP nonce for the server-emitted initialization script. | InitColorSchemeScript |
Runnable native examples
Machine keys select example entries, not universal variant props. Native demo JSX/data stay unchanged; JGuang-authored acceptance fixtures are explicitly labelled.
- Native server rendering and hydration (light) ·
Init-light· JGuang-authored native acceptance - Native server rendering and hydration (dark) ·
Init-dark· JGuang-authored native acceptance - Native server rendering and hydration (system) ·
Init-system· JGuang-authored native acceptance
Actual usage example
JGuang-authored native acceptance fixture, not an upstream component implementation.
// JGuang-authored genuine SSR/hydration fixture using Material UI's native APIs.
import { useEffect, useSyncExternalStore } from "react";
import { ThemeProvider, createTheme, useColorScheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
export const modeStorageKey = "jguang-material-init-mode";
export const colorSchemeStorageKey = "jguang-material-init-scheme";
const theme = createTheme({ cssVariables: { colorSchemeSelector: "data" }, colorSchemes: { light: true, dark: true } });
export type Mode = "light" | "dark" | "system";
type Props = { defaultMode: Mode; zh: boolean };
const subscribeHydration = () => () => {};
const clientHydrated = () => true;
const serverHydrated = () => false;
function Controls({ defaultMode, zh }: Props) {
const { mode, systemMode, setMode } = useColorScheme();
const hydrated = useSyncExternalStore(subscribeHydration, clientHydrated, serverHydrated);
useEffect(() => {
const report = () => { const root = document.getElementById("root")!; parent.postMessage({ type: "jguang-preview-ready", token: new URLSearchParams(location.search).get("token") ?? "", height: Math.ceil(root.getBoundingClientRect().bottom + window.scrollY) }, location.origin); };
const frame = requestAnimationFrame(report);
const observer = new ResizeObserver(report);
observer.observe(document.getElementById("root")!);
return () => { cancelAnimationFrame(frame); observer.disconnect(); };
}, []);
const reset = () => {
// Remove only this fixture's namespaced preferences, never the website's.
for (const key of [modeStorageKey, `${colorSchemeStorageKey}-light`, `${colorSchemeStorageKey}-dark`]) localStorage.removeItem(key);
location.reload();
};
return <Stack spacing={2}><Typography variant="h5">{zh ? "原生配色初始化与水合" : "Native color initialization and hydration"}</Typography><Paper sx={{ p: 3 }}><Typography>{zh ? "默认模式" : "Default mode"}: {defaultMode}</Typography><Typography role="status" data-hydrated={hydrated ? "true" : "false"} data-native-mode={mode ?? "pending"} data-system-mode={systemMode ?? "pending"}>{zh ? "当前模式" : "Current mode"}: {mode ?? (zh ? "等待水合" : "Awaiting hydration")}</Typography><Stack direction="row" useFlexGap spacing={1} sx={{ mt: 2, flexWrap: "wrap" }}>{(["light", "dark", "system"] as const).map(value => <Button key={value} disabled={!mode} variant={mode === value ? "contained" : "outlined"} onClick={() => setMode(value)}>{zh ? ({ light: "浅色", dark: "深色", system: "跟随系统" })[value] : value}</Button>)}<Button disabled={!hydrated} onClick={reset}>{zh ? "清除演示偏好并刷新" : "Clear demo preference and reload"}</Button></Stack><Typography sx={{ mt: 2 }}>{zh ? "脚本在 React 启动前执行;按钮通过原生 useColorScheme 更新并保存偏好。该工具不是可见 UI 组件,演示面板是 JGuang 编写的验收代码。" : "The native script runs before React starts. Buttons update and persist preferences using useColorScheme. This utility is not a visible UI component; JGuang authored this acceptance panel."}</Typography><input aria-label={zh ? "原生日期" : "Native date"} type="date" defaultValue="2026-01-25" style={{ marginTop: 16 }} /></Paper></Stack>;
}
export default function ColorSchemeApp(props: Props) {
return <ThemeProvider theme={theme} defaultMode={props.defaultMode} modeStorageKey={modeStorageKey} colorSchemeStorageKey={colorSchemeStorageKey} disableTransitionOnChange><CssBaseline enableColorScheme /><Controls {...props} /></ThemeProvider>;
}
Example dependency boundaries
Native Core/Emotion acceptance fixture.
Direct Icons/System/Utils example imports require their matching 9.4.0 packages. Relative data/helpers are part of the example closure, not extra components. Remote images and simulated operations do not supply a backend.
Pinned upstream API metadata reference
These tables retain the upstream metadata, not a newly inferred generic type system. Conditional generics, inherited props and callback details are defined by the source declarations below. Theme defaults may override metadata defaults.
InitColorSchemeScript
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';
import { InitColorSchemeScript } from '@mui/material';
| Prop | Required | Upstream metadata type / constraint | Metadata default |
|---|---|---|---|
attribute | no | string | 'data-mui-color-scheme' |
colorSchemeNode | no | string | 'document.documentElement' |
colorSchemeStorageKey | no | string | 'mui-color-scheme' |
defaultDarkColorScheme | no | string | 'dark' |
defaultLightColorScheme | no | string | 'light' |
defaultMode | no | 'dark' | 'light' | 'system' | 'system' |
modeStorageKey | no | string | 'mui-mode' |
nonce | no | string | — |
Native source declarations
Declarations/imports are extracted from pinned source without flattening unions or external inheritance. Original English comments/types are source reference, not a claim of translated upstream prose. Shared types stay in their native packages.
vendor/src/InitColorSchemeScript/InitColorSchemeScript.tsx
import PropTypes from 'prop-types';
import SystemInitColorSchemeScript from '@mui/system/InitColorSchemeScript';
export interface InitColorSchemeScriptProps {
/**
* The default mode when the storage is empty (user's first visit).
* @default 'system'
*/
defaultMode?: 'system' | 'light' | 'dark' | undefined;
/**
* The default color scheme to be used in light mode.
* @default 'light'
*/
defaultLightColorScheme?: string | undefined;
/**
* The default color scheme to be used in dark mode.
* @default 'dark'
*/
defaultDarkColorScheme?: string | undefined;
/**
* The node (provided as string) used to attach the color-scheme attribute.
* @default 'document.documentElement'
*/
colorSchemeNode?: string | undefined;
/**
* localStorage key used to store `mode`.
* @default 'mui-mode'
*/
modeStorageKey?: string | undefined;
/**
* localStorage key used to store `colorScheme`.
* @default 'mui-color-scheme'
*/
colorSchemeStorageKey?: string | undefined;
/**
* DOM attribute for applying a color scheme.
* @default 'data-mui-color-scheme'
* @example '.mode-%s' // for class based color scheme
* @example '[data-mode-%s]' // for data-attribute without '='
*/
attribute?: 'class' | 'data' | string | undefined;
/**
* Nonce string to pass to the inline script for CSP headers.
*/
nonce?: string | undefined;
}
Post-install acceptance
Run strict types, production build and real interactions. Check keyboard labels/focus, disabled/error/read-only semantics where natively supported, both themes, narrow screens and reduced motion. Verify callbacks against the real host data; do not declare installation complete from copying a prompt. Initialization fixtures also require server HTML and warning-free hydration.
Source and license
https://github.com/mui/material-ui/tree/809a7717b4c050ba3f69b75300689f07c050a16e
MIT · @mui/material@9.4.0. Vendor originals and license are preserved. Full original upstream prose remains in vendor/docs and is not represented as fully translated.