Reputation: 21
I have setup my website using Next.js 13 appDir and I am using next-theme's way of working around appDir as you can see in this issue: https://github.com/pacocoursey/next-themes/issues/152
What I want to do is to force a theme on the home page and allow the theme to toggle between dark and light mode. I saw that next-theme's doc has a section explaining how to do it on the Pages directory:https://www.npmjs.com/package/next-themes#:~:text=Force%20page%20to%20a%20theme
It seems like you just have to set a theme variable on the page component and pass it up to the layout so you can pass it as a prop to the theme provider.
How can I do that using appDir?
page.tsx
const Home = async () => {
return (
<div className="overflow-hidden bg-cloud">
{/*... my code*/}
</div>
)
}
Home.theme = 'light'
export default Home
layout.tsx
import '@/styles/globals.css'
import { IBM_Plex_Sans } from 'next/font/google'
import Providers from './providers'
const IBMPlexSans = IBM_Plex_Sans({
weight: ['100', '200', '300', '400', '700'],
subsets: ['latin'],
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" suppressHydrationWarning>
<body className={`${IBMPlexSans.className} text-night-dark`}>
<Providers defaultTheme="system" enableSystem>
{children}
</Providers>
</body>
</html>
)
}
providers.tsx
'use client'
import { ThemeProvider as NextThemeProvider } from 'next-themes'
import { ThemeProviderProps } from 'next-themes/dist/types'
const Providers = ({ children, ...props }: ThemeProviderProps) => {
return <NextThemeProvider {...props}>{children}</NextThemeProvider>
}
export default Providers
Tried using the force property on theme provider but makes it impossible to toggle between dark mode and light mode in the subsequent pages.
Upvotes: 0
Views: 3257
Reputation: 11
The strategy I use to solve this is wrapping that page with a layout or with a client component that uses the setTheme
function returned from the useTheme
hook.
page-theme.tsx
'use client';
import { useTheme } from 'next-themes';
export default function PageTheme({ children }: {children: React.ReactNode}) {
const { setTheme } = useTheme();
useEffect(() => {
setTheme('light'); //set your theme here after component mounts
}, []);
return <div>{children</div>;
}
page.tsx
const Home = async () => {
return (
<PageTheme>
<div className="overflow-hidden bg-cloud">
{/*... my code*/}
</div>
</PageTheme>
);
}
export default Home
Upvotes: 1