Я использую Next.js для своего личного бренда OXINION. Vercel представила Next.js 13 в октябре 2022 года. Поэтому я решил перейти на новую версию и адаптироваться к новой структуре каталогов «Приложения».
- Система маршрутизации
2. Добавьте Styled-компоненты в проект
Помните, мы создавали _document.tsx
для базовой настройки?
Библиотеки CSS-in-JS, которым требуется JavaScript во время выполнения, в настоящее время не поддерживаются в серверных компонентах.
- Создайте компонент глобального реестра, используя API стилевых компонентов, чтобы собрать все правила стиля CSS, созданные во время рендеринга, и соответствующую функцию для получения этих правил.
- Создайте клиентский компонент, используя крючок
useServerInsertedHTML
, чтобы вставить стили, собранные в реестре, в HTML-тег<head>
корневого макета.
// 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> ); }
В app/layout.tsx
добавьте свой собственный globalStyles.ts.
import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "@/styles/globals.css"; import Header from "@/components/Header"; import StyledComponentsRegistry from "@/lib/registry"; import GlobalStyles from "@/styles/GlobalStyles"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { title: "OXINION", description: "The Future of Travel", }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body className={inter.className}> <StyledComponentsRegistry> <GlobalStyles /> <Header /> {children} </StyledComponentsRegistry> </body> </html> ); }
Кроме того, я хотел бы продолжать использовать ThemeProvider, поэтому я создал отдельный файл под названием Providers.tsx, как будто мне не нравится наличие 'use client'
в вашем файле layout.tsx
. Кроме того, я добавил ответный запрос в Providers.tsx.
"use client"; import { ThemeProvider } from "styled-components"; import theme from "@/styles/theme"; import StyledComponentsRegistry from "@/lib/registry"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; const Providers = (props: React.PropsWithChildren) => { const queryClient = new QueryClient(); return ( <QueryClientProvider client={queryClient}> <StyledComponentsRegistry> <ThemeProvider theme={theme}>{props.children}</ThemeProvider> </StyledComponentsRegistry> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ); }; export default Providers;