-
Notifications
You must be signed in to change notification settings - Fork 0
Usage
Emilio Romero edited this page Jun 9, 2026
·
24 revisions
import { createContext, useContext, useState, type ReactNode } from 'react';
import Umbra, { type Options } from '@emrocode/umbra';
const options: Partial<Options> = {
autoMatchTheme: true,
// useColorScheme: ['#ffffff', '#000000'],
// useStorage: 'local',
// usePlugins: []
}
let umb = new Umbra(options);
const ThemeContext = createContext<{
theme: string;
toggleTheme: () => void;
} | null>(null);
export const ThemeProvider = ({ children }: { children: ReactNode }) => {
const [theme, setTheme] = useState<string>(umb.getCurrentTheme());
const toggleTheme = () => {
umb.toggleTheme();
setTheme(umb.getCurrentTheme());
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};To prevent the Flash of Unstyled Content (FOUC) when using Umbra with Server-Side Rendering (SSR) in Next.js, you must inject an inline, blocking script into your RootLayout. This ensures the user's preferred theme is applied to the HTML document before the browser renders the page.
Important
Add the "use client" directive to the top of any theme toggle or provider that interacts with localStorage or Umbra dynamically. Keep RootLayout as a Server Component to preserve optimal caching and SEO performance.
Implement this structure in your app/layout.tsx file:
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<script
dangerouslySetInnerHTML={{
__html: `(function(){try{var t=localStorage.getItem("theme");if(t)document.documentElement.setAttribute("data-theme",t)}catch(e){}})()`,
}}
/>
</head>
<body>{children}</body>
</html>
)
}v3.x
// tailwind.config.js
darkMode: ['selector', '[data-theme="dark"]']v4.x
@import "tailwindcss";
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
@theme {
--color-background: #fff;
--color-foreground: #000;
}
@variant dark {
--color-background: #000;
--color-foreground: #fff;
}
@layer base {
html,
body {
@apply bg-background text-foreground;
}
}