Как определить тему в nextJS с кастомным хуком на zustand
Вопрос заключается как мне определить тему для всего моего приложения, через хук если nextJs это северный рендор,
есть хранилище zustand
import { create } from "zustand";
import { persist } from 'zustand/middleware';
const getSystemTheme = () => {
if (typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
}
export const useThemeStore = create(persist((set, get) => ({
theme: 'system',
setTheme: (newTheme) => set({ theme: newTheme }),
getSystemTheme: () => getSystemTheme(),
getCurrentTheme: () => {
const state = get();
const systemTheme = getSystemTheme();
if (state.theme === 'system') return systemTheme;
else return state.theme;
}
}), {
name: 'app-theme'
}))
Ничего не обычного определяем тему, если системная возвращаем её, или выбранную пользователем, и как мне его определить в моем rootLayout чтобы тема определялась на всем приложение.
Легким способом можно было бы сделать так
import { Rubik } from 'next/font/google'
import './globals.css'
import ToastProvider from './ui/oneToasty/ToastProvider'
import { useThemeStore } from '@/store/useThemeStore'
const inter = Rubik({ subsets: ['latin', 'cyrillic'] })
export const metadata = {
title: 'web title',
description: 'bla bla bla',
}
export default function RootLayout({ children }) {
const { getCurrentTheme } = useThemeStore(state => ({
getCurrentTheme: state.getCurrentTheme,
}))
return (
<html lang="en" className={getCurrentTheme()}>
<body className={inter.className}>
<ToastProvider options={{
position: 'top-right',
toastsDefault: {
width: '21rem',
orientation: 'horizontal',
}
}}>
{children}
</ToastProvider>
</body>
</html>
)
}
Но нет useThemeStore это хук, и следовательно я получаю ошибку что его можно использовать на клиентской части, а сделать 'use client' тоже нельзя, так-как он северный и например metadata не будет.... Поэтому я в тупике