SSRとシステムカラーモード
サーバーレンダリング、ハイドレーション、システムカラーモードの仕組みを説明します。
このライブラリは決定的なサーバーマークアップをレンダリングし、document.documentElementを変更せずにReactハイドレーションをサポートします。カラーモードはプロバイダー自身のスコープで管理されます。
サーバーセーフなデータエントリ
React Server Componentsやその他のサーバーモジュールから、Reactを含まないエントリを使ってテーマを作成したりトークンを調べたりできます。
import { createTheme } from '@language-lit/material3-expressive/theme'
import { defaultTokenSet } from '@language-lit/material3-expressive/tokens'
export const theme = createTheme({
density: defaultTokenSet.system.density,
})Reactコンポーネントとフックは、クライアントで利用できるモジュール内でのみルートエントリから読み込んでください。
決定的なシステムモード
colorMode="system"では、サーバーと最初のハイドレーション時のスナップショットとしてsystemModeFallbackを使います。デフォルトはlightです。静的CSSは独立してprefers-color-schemeを評価するため、Reactがメディアクエリーを購読する前から、ライト/ダークの表示スキームは正しくなります。
'use client'
import type { ReactNode } from 'react'
import { Material3Provider } from '@language-lit/material3-expressive'
import type { Material3Theme } from '@language-lit/material3-expressive/theme'
export function Providers({
children,
theme,
}: {
children: ReactNode
theme: Material3Theme
}) {
return (
<Material3Provider
theme={theme}
colorMode="system"
systemModeFallback="light"
>
{children}
</Material3Provider>
)
}テーマオブジェクトはシリアライズ可能で、サーバーからクライアントへの境界を越えて渡せます。
任意の解決済みモード初期化
ほとんどのアプリケーションでは静的スタイルシートだけで十分です。ハイドレーション前にアプリケーションコードからdata-m3e-resolved-color-modeを読む場合は、プロバイダーのスコープ付き初期化スクリプトを有効にしてください。
<Material3Provider
colorMode="system"
preventColorSchemeFlash
nonce={contentSecurityPolicyNonce}
>
{children}
</Material3Provider>このスクリプトが更新するのはプロバイダー要素だけです。ポリシーで必要な場合は、リクエストのCSP nonceを渡してください。スクリプトはデフォルトでは出力されません。
Next.js App Router
ルートレイアウトから/styles.cssを読み込み、その配下に小さなクライアントプロバイダーコンポーネントをレンダリングします。カスタムテーマデータはサーバーモジュール内で/themeを通じて作成し、そのサーバーモジュールからクライアント用ルートバレルを読み込まないでください。
Next.jsアダプターは公開APIに含まれていません。同じプロバイダーとシリアライズ済みテーマは、Vite、その他のSSRフレームワーク、またはrenderToString/hydrateRootを直接使う構成でも動作します。
ネストしたスコープとハイドレーション
ネストした各プロバイダーは完全な.m3e-themeスコープを出力します。サーバーレンダリングとクライアントの最初のレンダリングでは、テーマ、colorMode、systemModeFallbackに同じ値を使ってください。その後のprops変更は通常のReact状態の変更であり、ハイドレーションの手段ではありません。