CSS-in-JS
Warnung: CSS-in-JS-Bibliotheken, die Laufzeit-JavaScript benötigen, werden derzeit in Server Components nicht unterstützt. Die Verwendung von CSS-in-JS mit neueren React-Funktionen wie Server Components und Streaming erfordert, dass Bibliotheksautoren die neueste Version von React unterstützen, einschließlich Concurrent Rendering.
Wir arbeiten mit dem React-Team an Upstream-APIs, um CSS- und JavaScript-Assets mit Unterstützung für React Server Components und Streaming-Architektur zu handhaben.
Die folgenden Bibliotheken werden in Client Components im app
-Verzeichnis unterstützt (alphabetisch):
chakra-ui
kuma-ui
@mui/material
@mui/joy
pandacss
styled-jsx
styled-components
stylex
tamagui
tss-react
vanilla-extract
Die folgenden Bibliotheken arbeiten derzeit an der Unterstützung:
Gut zu wissen: Wir testen verschiedene CSS-in-JS-Bibliotheken und werden weitere Beispiele für Bibliotheken hinzufügen, die React 18-Funktionen und/oder das
app
-Verzeichnis unterstützen.
Wenn Sie Server Components gestalten möchten, empfehlen wir die Verwendung von CSS Modules oder anderen Lösungen, die CSS-Dateien ausgeben, wie PostCSS oder Tailwind CSS.
Konfiguration von CSS-in-JS in app
Die Konfiguration von CSS-in-JS ist ein dreistufiger Opt-in-Prozess, der Folgendes umfasst:
- Ein Style-Registry, um alle CSS-Regeln während eines Renders zu sammeln.
- Den neuen
useServerInsertedHTML
-Hook, um Regeln vor jeglichem Injektion einzufügen, der sie verwenden könnte. - Eine Client Component, die Ihre App während des initialen Server-Side-Renderings mit der Style-Registry umschließt.
styled-jsx
Die Verwendung von styled-jsx
in Client Components erfordert Version v5.1.0
. Erstellen Sie zunächst eine neue Registry:
'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
}) {
// Stylesheet nur einmal mit lazy initial state erstellen
// 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 }) {
// Stylesheet nur einmal mit lazy initial state erstellen
// 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>
}
Dann umschließen Sie Ihr Root Layout mit der Registry:
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
Nachfolgend ein Beispiel für die Konfiguration von styled-components@6
oder neuer:
Aktivieren Sie zunächst styled-components in next.config.js
.
module.exports = {
compiler: {
styledComponents: true,
},
}
Verwenden Sie dann die styled-components
-API, um eine globale Registry-Komponente zu erstellen, die alle während eines Renders generierten CSS-Style-Regeln sammelt, sowie eine Funktion, um diese Regeln zurückzugeben. Verwenden Sie dann den useServerInsertedHTML
-Hook, um die in der Registry gesammelten Styles in das <head>
-HTML-Tag im Root-Layout einzufügen.
'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
}) {
// Stylesheet nur einmal mit lazy initial state erstellen
// 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 }) {
// Stylesheet nur einmal mit lazy initial state erstellen
// 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>
)
}
Umschließen Sie die children
des Root-Layouts mit der Style-Registry-Komponente:
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>
)
}
Gut zu wissen:
- Während des Server-Renderings werden Styles in eine globale Registry extrahiert und in den
<head>
Ihres HTML eingefügt. Dadurch wird sichergestellt, dass die Style-Regeln vor jeglichem Inhalt platziert werden, der sie verwenden könnte. In Zukunft könnten wir eine kommende React-Funktion verwenden, um zu bestimmen, wo die Styles eingefügt werden sollen.- Während des Streamings werden Styles aus jedem Chunk gesammelt und an bestehende Styles angehängt. Nachdem das Client-Side-Hydration abgeschlossen ist, übernimmt
styled-components
wie gewohnt und fügt weitere dynamische Styles ein.- Wir verwenden speziell eine Client Component auf der obersten Ebene des Baums für die Style-Registry, da dies effizienter ist, um CSS-Regeln zu extrahieren. Es vermeidet die Neugenerierung von Styles bei nachfolgenden Server-Rendern und verhindert, dass sie im Server-Component-Payload gesendet werden.
- Für fortgeschrittene Anwendungsfälle, in denen Sie individuelle Eigenschaften der styled-components-Kompilierung konfigurieren müssen, können Sie unsere Next.js styled-components API-Referenz lesen, um mehr zu erfahren.