reactjsprimereact

How can one have a theme switcher in primereact


I would like to be in a position to switch between themes in primereact rather than import one theme and then it affects my whole app and I don't have an option to switch between dark or light mode.


Solution

  • i am a late to the party but here's my solution for Next.js (Pages Router)

    useLocalStorage of primereact is a bit weird so i had to use useLocalStorage from usehooks-ts

    // _app.tsx
    ...
    import { useLocalStorage } from "usehooks-ts";
    
    export const prefersTheme = () => {
        if (typeof window === "undefined") {
            return 'light'
        }
        const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
        return prefersDarkScheme.matches ? 'dark' : 'light';
    }
    
    export default function App({ Component, pageProps }: AppProps) {
        const [theme, setTheme] = useLocalStorage("theme", prefersTheme)
    
        const toggleTheme = () => {
            setTheme((prevTheme) => (prevTheme === 'dark' ? 'light' : 'dark'));
        };
    
        useEffect(() => {
            // If a theme is set, save it to localStorage and apply the theme
            if (theme) {
                const existingLink = document.getElementById('theme-link');
                if (existingLink) {
                    existingLink.remove();
                }
    
                const link = document.createElement('link');
                link.id = 'theme-link';
                link.rel = 'stylesheet';
                link.href = theme === 'dark'
                    ? '/themes/soho-dark/theme.css'
                    : '/themes/soho-light/theme.css';
    
                document.head.appendChild(link);
            }
        }, [theme]);
    
        ...
    }
    

    Make sure your themes are in public directory.