CSS-in-JS
警告: 現在、実行時の JavaScript が必要な CSS-in-JS ライブラリは、Server Components でサポートされていません。新しい React の機能である Server Components やストリーミングで CSS-in-JS を使用するには、並行 rendering を含む最新の React の version をライブラリの作者がサポートする必要があります。
私たちは React チームと協力して、上流 API を使って CSS と JavaScript のアセットを処理し、 React Server Components と Streaming アーキテクチャをサポートしています。
次のライブラリは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
ディレクトリに対応するライブラリの例を増やしていきます。
style Server Components を使用したい場合は、CSS ファイルを出力する他のソリューション、PostCSS やTailwind CSSなどと同様に、CSS Modulesの使用をお勧めします。
Configuring CSS-in-JS in app
CSS-in-JS の設定は、次のような 3 ステップのオプトインプロセスを含みます:
- 全ての CSS ルールを render に収集するための style registry。
- 新しい
useServerInsertedHTML
hook は、それらを使用する可能性のあるコンテンツの前にルールを注入するためのものです。 - 初期の server-side rendering の間にあなたの app を style レジストリで包み込む Client Component。
styled-jsx
styled-jsx
を Client Components で使用するには、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
}) {
// Only create stylesheet once with lazy initial state
// x-ref: 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>
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({ children }) {
// Only create stylesheet once with lazy initial state
// x-ref: 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>
}
次に、レジストリであなたのroot layoutをラップしてください:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
import StyledJsxRegistry from './registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
ここで例を見る 。
Styled Components
以下は、styled-components@6
またはそれ以降の Version の設定方法の一例です:
まず、next.config.js
で styled-components を有効にしてください。
module.exports = {
compiler: {
styledComponents: true,
},
}
次に、styled-components
の API を使用してグローバルレジストリの component を作成し、rendering 中に生成されたすべての CSS スタイルルールを収集し、それらのルールを返す関数を作成します。次に、useServerInsertedHTML
の hook を使用して、レジストリに収集された styles を、rootlayout の<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
}) {
// Only create stylesheet once with lazy initial state
// x-ref: 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>
)
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({ children }) {
// Only create stylesheet once with lazy initial state
// x-ref: 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
の root layout を style registry component でラップしてください:
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
ここで一例をご覧くださいView an example here 。
Good to know:
- server rendering 中に、 style はグローバルレジストリに抽出され、あなたの HTML の
<head>
にフラッシュされます。これにより、 styles のルールがそれを使用する可能性があるコンテンツの前に配置されることが保証されます。将来的には、これから登場する React の機能を用いて、 styles を注入する位置を決定するかもしれません。- ストリーミング中、各チャンクの styles が収集され、既存の styles に追加されます。クライアントサイドのハイドレーションが完了した後、
styled-components
は通常通りに引き続き、任意の dynamic styles を注入します。- 我々は特に Client Component をツリーのトップレベルで style レジストリに使用しています。なぜなら、この方法で CSS ルールを抽出する方が効率的だからです。それは styles を後続の server レンダリングで再生成するのを避け、それらが Server Component のペイロードで送信されるのを防ぎます。
- 詳細な使用例で、styled-components のコンパイルの個々のプロパティを設定する必要がある場合は、詳しくは当社のNext.js styled-components API referenceをご覧ください。