本文へスキップ
Material 3 Expressivev1.3.0-rc.1
ガイド

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状態の変更であり、ハイドレーションの手段ではありません。