React Themes
Adding dark mode to your Tanstack-Start React App when using shadcn/ui.
This guide assumes that you have already initialized the shadcn/ui in your Tanstack Start react app. If not then you can initialize it by following the Installation Guide here.
Installation
To add dark mode to your Tanstack-Start React App, you need to simply run following command:
npx shadcn@latest add https://mksingh.dev/r/tanstack/start/react/themes.json
Usage
Once you have installed the theme configuration, now let's add the functions and components.
import { getThemeServerFn, ThemeProvider, useTheme } from '@/lib/theme';
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: 'utf-8',
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1',
},
{
title: 'TanStack Start Starter - MKSingh',
},
],
links: [
{
rel: "stylesheet",
href: appCss,
},
],
}),
component: RootComponent,
beforeLoad: async () => await getThemeServerFn(),
loader: ({ context }) => context?.theme ? context : null,
});
function RootComponent() {
const themeValue = Route.useLoaderData();
return (
<ThemeProvider value={themeValue}>
<RootDocument>
<Outlet />
</RootDocument>
</ThemeProvider>
)
}
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
const { theme } = useTheme();
return (
<html className={theme} suppressHydrationWarning>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
<Devtools />
</body>
</html>
)
}
Theme switcher
How to implement the theme switcher?
useTheme
hook provides -
theme
which is the current theme and it can belight
ordark
onlydefinedBy
can besystem
oruser
which is the source of the themesetTheme
function to change the theme. It acceptslight
ordark
orsystem
as an argument
Example
I've used kibo-ui
as an example. It also works in same fashion like shadcn/ui.
You can explore at kibo-ui
However, you can use any other UI library as well.
Kibo-ui installation
You can install kibo-ui's components using
shadcn/ui
CLI or directly using kibo-ui
CLI.
Shadcn/ui CLI
npx shadcn@latest add https://www.kibo-ui.com/registry/theme-switcher.json
Kibo-ui CLI
npx kibo-ui@latest add theme-switcher
import { ThemeSwitcher } from '@/components/ui/kibo-ui/theme-switcher';
import { useTheme } from '@/lib/theme';
const ThemeSwitcherComponent = () => {
const { theme, definedBy, setTheme } = useTheme();
const value = definedBy === 'system' ? 'system' : theme;
return <ThemeSwitcher theme={value} onChange={setTheme} />
};