T
TanStack•3mo ago
sensitive-blue

Implement Dark Mode in TanStack Start

Hey @Jp, Thank you for sharing this. What does optimistic brings here? I would naively implement something like presented in this blog post https://nisabmohd.vercel.app/tanstack-dark
Implement Dark Mode in TanStack Start
Easily add dark mode to your TanStack Start app with a simple toggle and persistent theme preference across routes.
10 Replies
foreign-sapphire
foreign-sapphire•3mo ago
it doest wait for the server roundtrip to update the theme on the client
flat-fuchsia
flat-fuchsia•3mo ago
exactly this 😄 . like you could switch themes smoothly even though you network or browser performance is slow
foreign-sapphire
foreign-sapphire•3mo ago
GitHub
optimistic-theme-switcher/src/components/client-hint-check.tsx at m...
Contribute to jjppsia/optimistic-theme-switcher development by creating an account on GitHub.
foreign-sapphire
foreign-sapphire•3mo ago
client-hint-check.tsx
flat-fuchsia
flat-fuchsia•3mo ago
basically it prevents a "flash of incorrect content" (like wrong theme) on initial page load. it injects a script that checks for user preferences (like theme, timezone, or language) stored in cookies; if they are missing or old, it sets them so the server can render with the correct information. learned if from: - https://github.com/epicweb-dev/client-hints - https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Client_hints
GitHub
GitHub - epicweb-dev/client-hints: Eliminate a flash of incorrect c...
Eliminate a flash of incorrect content by using client hints - epicweb-dev/client-hints
MDN Web Docs
HTTP Client hints - HTTP | MDN
Client hints are a set of HTTP request header fields that a server can proactively request from a client to get information about the device, network, user, and user-agent-specific preferences. The server can determine which resources to send, based on the information that the client chooses to provide.
stuck-chocolate
stuck-chocolate•3mo ago
im curious how does this compare with just doing it all in the client/localstorage with a ScriptOnce in root to prevent FOUC? i have been using this very simple solution from @nize's template and it has been working well so far:
<ScriptOnce>
{`document.documentElement.classList.toggle(
'dark',
localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
)`}
</ScriptOnce>
<ScriptOnce>
{`document.documentElement.classList.toggle(
'dark',
localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
)`}
</ScriptOnce>
this ScriptOnce effectively runs before browser paint so there is no FOUC and a very simple themetoggle component here and to support reverting back to system theme in the ThemeToggle, i just delete the theme entry from localStorage and added useSyncExternalStore if I want to explicitly track changes to show "system theme" preference as an icon
exotic-emerald
exotic-emerald•3mo ago
same solution with the inline script here but im just using a regular script tag, not sure why are you using ScriptOnce? i saw the code and its just a script with an extra console log
stuck-chocolate
stuck-chocolate•3mo ago
I think it was to fix an issue with ssr/hydration: https://discord.com/channels/719702312431386674/1302275380471922861/1303157794811150449 https://discord.com/channels/719702312431386674/1313219828315721799/1340094571975151729 I'm not sure now though since you are right, it also works with a regular script tag so far
fair-rose
fair-rose•3mo ago
So to sum-up the following things happens: - The theme is read through the cookies and if not available through the browser user preferences - Client-hints is used prevent flash screen (initial page load) when the theme isn’t yet defined (system) - In order to change the theme the cookie is being updated through a server function hence the optimistic part Since there’s no suspense component involved, are we still benefiting from the suspense query?
flat-fuchsia
flat-fuchsia•3mo ago
the theme will always have a value: either "light," "dark," or "null." this is why we use useSuspenseQuery. additionally, tanstack router has built-in support for suspense and error boundaries. check tkdodo's blog post: https://tkdodo.eu/blog/the-beauty-of-tan-stack-router
The Beauty of TanStack Router
Yes, it's type-safe, but there's so much more to love about TanStack Router.
No description

Did you find this page helpful?