Lang x Lang

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 でサポートされています(アルファベット順):

以下の人々が現在、サポートに取り組んでいます:

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 ステップのオプトインプロセスを含みます:

  1. 全ての CSS ルールを render に収集するための style registry
  2. 新しいuseServerInsertedHTML hook は、それらを使用する可能性のあるコンテンツの前にルールを注入するためのものです。
  3. 初期の server-side rendering の間にあなたの app を style レジストリで包み込む Client Component。

styled-jsx

styled-jsxを Client Components で使用するには、v5.1.0が必要です。まず、新しいレジストリを作成します:

app/registry.tsx
'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>
}
app/registry.js
'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をラップしてください:

app/layout.tsx
import StyledJsxRegistry from './registry'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <StyledJsxRegistry>{children}</StyledJsxRegistry>
      </body>
    </html>
  )
}
app/layout.js
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 を有効にしてください。

next.config.js
module.exports = {
  compiler: {
    styledComponents: true,
  },
}

次に、styled-componentsの API を使用してグローバルレジストリの component を作成し、rendering 中に生成されたすべての CSS スタイルルールを収集し、それらのルールを返す関数を作成します。次に、useServerInsertedHTMLの hook を使用して、レジストリに収集された styles を、rootlayout の<head>の HTML タグに挿入します。

lib/registry.tsx
'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>
  )
}
lib/registry.js
'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 でラップしてください:

app/layout.tsx
import StyledComponentsRegistry from './lib/registry'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
      </body>
    </html>
  )
}
app/layout.js
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をご覧ください。

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use