CSS-in-JS
注意: 実行時の JavaScript ランタイムが必要な CSS-in-JS ライブラリは、現在 Server Components でサポートされていません。Server Components や Streaming など、新しい React 機能と CSS-in-JS を使用するには、ライブラリの作者が React の最新バージョン( 並行レンダリングを含む)をサポートする必要があります。
現在 Next.js チームは React Server Components とストリーミングアーキテクチャをサポートする CSS と JavaScript アセットを扱うための上流の API について、React チームと協力して作業しています。
app
ディレクトリ内の Client Components で以下のライブラリがサポートされています(アルファベット順):
chakra-ui
kuma-ui
@mui/material
pandacss
styled-jsx
styled-components
stylex
tamagui
tss-react
vanilla-extract
現在対応を進めているライブラリ:
Good to know: 様々な CSS-in-JS ライブラリを試し、React 18 の機能や
app
ディレクトリをサポートするライブラリについて、さらに多くの例を追加する予定です。
Server Components をスタイリングする場合、CSS ファイルを出力する CSS Modules や PostCSS、Tailwind CSS などの他の解決策の使 用をお勧めします。
app
での CSS-in-JS の設定
CSS-in-JS を設定するには、以下の 3 ステップで構成されるオプトインのプロセスが必要です:
- レンダリング中のすべての CSS ルールを収集する スタイルレジストリ
- ルールを使用する可能性のあるすべてのコンテンツの前にルールを注入する
useServerInsertedHTML
フック - 初期サーバーサイドレンダリング中にアプリケーションをスタイルレジストリでラップする Client Component
styled-jsx
Client Components で styled-jsx
を使用するには、v5.1.0
を使用します。まず、新しいレジストリを作成します:
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({
children,
}: {
children: React.ReactNode
}) {
// lazy な初期状態で、一度だけスタイルシートを作成する
// 参考: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
次に、レジストリでルートレイアウトをラップします:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
例を見る.
Styled Components
以下は、styled-components@6
以降を設定する方法の例です:
まず、next.config.js
で styled-components を有効にします。
module.exports = {
compiler: {
styledComponents: true,
},
}
次に styled-components
API を使用して、描画中に生成されたすべての CSS スタイルルールを収集するグローバルレジストリコンポーネントと、それらのルールを返す関数を作成します。その後、useServerInsertedHTML
フックを使用して、ルートレイアウトの <head>
HTML タグにレジストリで収集されたスタイルを注入します。
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode
}) {
// lazy な初期状態で、一度だけスタイルシートを作成する
// 参考: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
ルートレイアウトの children
をスタイルレジストリコンポーネントでラップします:
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}