TanStackT
TanStack6mo ago
4 replies
popular-magenta

Better way to get theme?

Im accessing the theme cookie on
__root
during
loader
, but every client-side navigation triggers it.

export const Route = createRootRouteWithContext<RouterAppContext>()({
  component: RootComponent,
  loader: () => getThemeServerFn(),
});

function RootComponent() {
  const data = Route.useLoaderData();

  return <ThemeProvider theme={data}>{/*  */}</ThemeProvider>;
}

function RootDocument({children}: Readonly<{children: React.ReactNode}>) {
  const theme = Route.useLoaderData();

  return (
    <html lang="en" className={theme} suppressHydrationWarning>
      {/*  */}
    </html>
  );
}


import {createServerFn} from "@tanstack/react-start";
import {getCookie, setCookie} from "@tanstack/react-start/server";

type Theme = "dark" | "light";

const storageKey = "ui-theme";

export const getThemeServerFn = createServerFn().handler(async () => {
  return (getCookie(storageKey) || "light") as Theme;
});

export const setThemeServerFn = createServerFn({method: "POST"})
  .validator((data: unknown) => {
    if (typeof data != "string" || (data != "dark" && data != "light")) {
      throw new Error("Invalid theme provided");
    }
    return data as Theme;
  })
  .handler(async ({data}) => {
    setCookie(storageKey, data);
  });


Any better approach to just do it one time ?
Was this page helpful?