Reputation: 51
i want to add themeprovider to my app so i can easily change between dark and light mode
this how my layout.tsx looks like:
import "./globals.css";
import "@/styles/nav.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { ApolloProvider } from "@apollo/client";
import createApolloClient from "./apollo";
import Header from "./header";
import { ThemeProvider } from "styled-components";
import { darkTheme } from "@/styles/ThemeConfig";
const inter = Inter({ subsets: ["latin"] });
const client = createApolloClient();
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<ThemeProvider theme={darkTheme}>
<Header></Header>
{children}
</ThemeProvider>
</body>
</html>
);
}
i'm getting error: Server Error Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component
if i'm adding use client to layout.tsx my page still dont work and i'm getting other error Failed to compile ./src\app\layout.tsx ReactServerComponentsError:
You are attempting to export "metadata" from a component marked with "use client", which is disallowed. Either remove the export, or the "use client" directive. Read more: https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive
how to add theme provider?
import { createGlobalStyle } from "styled-components";
export const lightTheme = {
body: "#FFF",
text: "#363537",
toggleBorder: "#FFF",
background: "#363537",
};
export const darkTheme = {
body: "#363537",
text: "#FAFAFA",
toggleBorder: "#6B8096",
background: "#999",
};
export const GlobalStyles = createGlobalStyle`
body {
background: ${({ theme }) => theme.body};
color: ${({ theme }) => theme.text};
font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif;
transition: all 0.50s linear;
}
`;
Upvotes: 5
Views: 10445
Reputation: 4146
You are getting the error:
Server Error Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more:
https://nextjs.org/docs/messages/context-in-server-component
because ThemeProvider
is supposed to be run on client-side (meaning a client-component). All client components in Next.js need to be marked with "use client"
directive.
Since your ThemeProvider
component is from styled-components
, that means you cannot mark it as "use client"
.
The next option is to make RootLayout
as a client component. But,
The root layout is a Server Component by default and can not be set to a Client Component.
https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#layouts
So you cannot add "use client"
to src/app/layout.tsx
as well.
That means the only option is to create another component (which will be a client component) and you need to use ThemeProvider
inside it. Then use this component in RootLayout
.
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<ThemeClient>
<Header></Header>
{children}
</ThemeClient>
</body>
</html>
);
}
"use client"
import { darkTheme } from "@/styles/ThemeConfig";
export default function ThemeClient({
children,
}: {
children: React.ReactNode;
}) {
return (
<ThemeProvider theme={darkTheme}>
{children}
</ThemeProvider>
)
}
Upvotes: 10