Frameworks
Vite
Setup guide for Vite and Create React App
Installation
npm install better-themesSetup
Update your root component
In your main entry file (typically main.tsx or App.tsx), wrap your app with ThemeProvider:
import { ThemeProvider } from "better-themes";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./global.css";
createRoot(document.getElementById("root")!).render(
<ThemeProvider>
<App />
</ThemeProvider>
);Style your app
:root {
--background: white;
--foreground: black;
}
.dark {
--background: black;
--foreground: white;
}
body {
background: var(--background);
color: var(--foreground);
}Create a theme switcher component
import { useTheme } from "better-themes";
import { useEffect, useState } from "react";
export function ThemeSwitcher() {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return null;
}
return (
<button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
Toggle theme
</button>
);
}Complete Example
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./global.css";
import App from "./App.tsx";
import { ThemeProvider } from "better-themes";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</StrictMode>
);import { useTheme } from "better-themes";
import { useEffect, useState } from "react";
export function ThemeSwitcher() {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return null;
}
return (
<button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
{theme === "dark" ? "Light" : "Dark"}
</button>
);
}Notes
- Use the default export for Vite
- If using Vite with SSR, add
suppressHydrationWarningto the<html>tag - Works with both Vite and Create React App
Example
View a complete example implementation: Vite Example
Try the live demo: Live Demo