Custom theme
Create branded themes
Create custom themes for your documentation.
Basic theme#
Add CSS variables to your global stylesheet:
css
:root {
--bg: #0a0a0a;
--surface: #141414;
--line: #262626;
--fg: #fafafa;
--muted: #737373;
--dim: #525252;
--accent: #3b82f6;
}Brand colors#
Match your brand by customizing the accent color:
css
:root {
--accent: #6366f1;
--accent-hover: #818cf8;
--accent-muted: rgba(99, 102, 241, 0.1);
}Use in tailwind config:
ts
export default {
theme: {
extend: {
colors: {
accent: {
DEFAULT: "var(--accent)",
hover: "var(--accent-hover)",
muted: "var(--accent-muted)",
},
},
},
},
};Light/dark mode#
Support both themes:
css
:root {
--bg: #0a0a0a;
--surface: #141414;
--line: #262626;
--fg: #fafafa;
--muted: #737373;
--accent: #3b82f6;
}
.light {
--bg: #ffffff;
--surface: #f5f5f5;
--line: #e5e5e5;
--fg: #171717;
--muted: #737373;
--accent: #2563eb;
}Theme provider#
Create a theme provider component:
tsx
"use client";
import { createContext, useContext, useEffect, useState } from "react";
type Theme = "light" | "dark" | "system";
const ThemeContext = createContext<{
theme: Theme;
setTheme: (theme: Theme) => void;
}>({ theme: "system", setTheme: () => {} });
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<Theme>("system");
useEffect(() => {
const stored = localStorage.getItem("theme") as Theme;
if (stored) setTheme(stored);
}, []);
useEffect(() => {
const root = document.documentElement;
root.classList.remove("light", "dark");
if (theme === "system") {
const system = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
root.classList.add(system);
} else {
root.classList.add(theme);
}
localStorage.setItem("theme", theme);
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
export const useTheme = () => useContext(ThemeContext);Theme toggle#
tsx
"use client";
import { useTheme } from "@/components/theme";
export function ThemeToggle() {
const { theme, setTheme } = useTheme();
return (
<button
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
className="p-2 rounded hover:bg-surface"
aria-label="toggle theme"
>
{theme === "dark" ? (
<svg
className="w-4 h-4"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
>
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
</svg>
) : (
<svg
className="w-4 h-4"
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
>
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" />
</svg>
)}
</button>
);
}Preset themes#
Create multiple theme options:
css
.theme-blue {
--accent: #3b82f6;
}
.theme-green {
--accent: #22c55e;
}
.theme-purple {
--accent: #a855f7;
}
.theme-orange {
--accent: #f97316;
}Theme selector#
Let users pick a theme:
tsx
"use client";
import { useState, useEffect } from "react";
const themes = ["blue", "green", "purple", "orange"];
export function ThemeSelector() {
const [selected, setSelected] = useState("blue");
useEffect(() => {
const stored = localStorage.getItem("accent-theme");
if (stored) setSelected(stored);
}, []);
const selectTheme = (theme: string) => {
const root = document.documentElement;
themes.forEach((t) => root.classList.remove(`theme-${t}`));
root.classList.add(`theme-${theme}`);
localStorage.setItem("accent-theme", theme);
setSelected(theme);
};
return (
<div className="flex gap-2">
{themes.map((theme) => (
<button
key={theme}
onClick={() => selectTheme(theme)}
className={`w-6 h-6 rounded-full ${
selected === theme
? "ring-2 ring-offset-2 ring-offset-bg ring-fg"
: ""
}`}
style={{
backgroundColor:
theme === "blue"
? "#3b82f6"
: theme === "green"
? "#22c55e"
: theme === "purple"
? "#a855f7"
: "#f97316",
}}
aria-label={`${theme} theme`}
/>
))}
</div>
);
}Code block themes#
Customize syntax highlighting:
css
:root {
--code-bg: #1e1e1e;
--code-string: #ce9178;
--code-keyword: #569cd6;
--code-function: #dcdcaa;
--code-comment: #6a9955;
--code-number: #b5cea8;
}Custom fonts#
Add brand fonts:
css
:root {
--font-sans: "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", monospace;
}Use in tailwind:
ts
export default {
theme: {
extend: {
fontFamily: {
sans: ["var(--font-sans)"],
mono: ["var(--font-mono)"],
},
},
},
};