Dark Mode
Has anyone created the Theme Provider ShadCN suggests for the "Vite" solution? Where did you wrap?
I tried wrapping..
and it threw an error that localStorage is not defined. I believe this is because it was running on the server?
27 Replies
fair-rose•7mo ago
yes this runs on the server during SSR
fair-rose•7mo ago
GitHub
GitHub - ally-ahmed/tss-blog-starter: A blog/portfolio starter proj...
A blog/portfolio starter project built with TanStack Start. - ally-ahmed/tss-blog-starter
vicious-goldOP•7mo ago
Sheeeeeesh. Bro, you're on the $$!
Fast AF 🙂
vicious-goldOP•7mo ago
Hmm, seems this impl causes a hydration
hook.js:608 A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used: - A server/client branchif (typeof window !== 'undefined')
. - Variable input such asDate.now()
orMath.random()
which changes each time it's called. - Date formatting in a user's locale which doesn't match the server. - External changing data without sending a snapshot of it along with the HTML. - Invalid HTML tag nesting. It can also happen if the client has a browser extension installed which messes with the HTML before React loaded. https://react.dev/link/hydration-mismatch ... <MatchesInner> <CatchBoundary getResetKey={function getResetKey} errorComponent={function ErrorComponent} ...> <CatchBoundaryImpl getResetKey={function getResetKey} onCatch={function onCatch}> <MatchImpl matchId="root"> <SafeFragment fallback={null}> <CatchBoundary getResetKey={function getResetKey} errorComponent={function errorComponent} ...> <CatchBoundaryImpl getResetKey={function getResetKey} onCatch={function onCatch}> <CatchNotFound fallback={function fallback}> <CatchBoundary getResetKey={function getResetKey} onCatch={function onCatch} ...> <CatchBoundaryImpl getResetKey={function getResetKey} onCatch={function onCatch}> <MatchInnerImpl matchId="root"> <RootComponent> <RootDocument> <html - data-theme="dark" - style={{color-scheme:"dark"}} >
hydrateRoot – React
The library for web and native user interfaces
vicious-goldOP•7mo ago
any thoughts before I dive in?
fair-rose•7mo ago
thats unavoidable
the server cannot possibly know your system theme
so you need to accept that and ignore that hydration error / suppress
vicious-goldOP•7mo ago
okay, so safe to ignore this one here?
fair-rose•7mo ago
yes
vicious-goldOP•7mo ago
Perfect, I think it just threw a flag - my guess is nextjs or something there squashes this type of error?
fair-rose•7mo ago
in which way?
vicious-goldOP•7mo ago
I just had never experienced this hydration error in nextjs with theming
fair-rose•7mo ago
GitHub
GitHub - pacocoursey/next-themes: Perfect Next.js dark mode in 2 li...
Perfect Next.js dark mode in 2 lines of code. Support System preference and any other theme with no flashing - pacocoursey/next-themes
fair-rose•7mo ago

vicious-goldOP•7mo ago
AH, there it is. That's what I was poking at
great shout
plain-purple•7mo ago
Just as a note we allow our users to change the theme manually too. Once they do that we save a cookie which allows accessing it on the server so the initial theme used for SSR is already the right one 🙂 For system ofc this does not work 😄
fair-rose•7mo ago
but you dont need the cookie
just store in localStorage
this just prevents the hydration error that is suppressed anyhow
for the initial load
where no theme is known
plain-purple•7mo ago
but if i use localStorage I can't know what the right theme is on the server right? So i get hydration error and possibly also a flash of the wrong UI while it changes the theme UI on the client?
fair-rose•7mo ago
you can never know the theme on the server for the initial load
plain-purple•7mo ago
i run this in my beforeLoad:
And then use that value and pass it into my MUI ThemeProvider.
So if the user has already choosen a theme in the past (e.g. manually switching to high-contrast or dark) I can know the theme on the server at the initial load?
Or am i missing something.
I know that this will never work on the very very first load when the user visits my app the very first time.
fair-rose•7mo ago
you just need to ensure that you run the script that reads from local storage executes early enough
then you wont get a flash
plain-purple•7mo ago
I might try that again, but this now works pretty good so I am inclined to just leave it for now as long as you don't tell me that this is garbage 😄
already spent too much time dealing with hydration errors.
fair-rose•7mo ago
it's not garbage.
we also use a cookie on tanstack.com
for theming
just wanted to point out you can do it purely client side
see this example above
plain-purple•7mo ago
ok nice! 🙂
wise-white•7mo ago
i have
vicious-goldOP•7mo ago
Gonna try working through this tonight now that ShadCN supports tailwind v4
Has anyone does this with Tailwind V4 yet?
Okay, I have this working now with V4.
Here's a different approach than the ThemeProvider...
vicious-goldOP•7mo ago
@Manuel Schiller Here's a NICE starter^ was really helpful getting tailwind v4 up and running too:
https://github.com/dotnize/tanstarter/tree/main
GitHub
GitHub - dotnize/tanstarter: minimal TanStack Start template with B...
minimal TanStack Start template with Better Auth, Drizzle ORM, shadcn/ui - dotnize/tanstarter
wise-white•7mo ago
I also had to add this in to my Head to stop the flash as well as put ThemeProvider around the Body tag. As of now i have no problems anymore