T
TanStack•8mo ago
wise-white

I am getting a weird issue with my production build in tanstack start

My Sign In page looks like this during dev and everything works fine but in production the page is duplicated somehow The second image is how the page looked like in prod (Zoomed out a bit to be able to take a screenshot)
No description
No description
24 Replies
equal-aqua
equal-aqua•8mo ago
can you share you routes folder ?
equal-aqua
equal-aqua•8mo ago
I had some similar issues with this as well and I had to add an _ to my file name at the end. Take a look at the _ Suffix from the doc: https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing#pathless-routes
File-Based Routing | TanStack Router React Docs
Most of the TanStack Router documentation is written for file-based routing and is intended to help you understand in more detail how to configure file-based routing and the technical details behind h...
manual-pink
manual-pink•8mo ago
where is this deployed?
wise-white
wise-whiteOP•8mo ago
Vercel But the behaviour is inconsistent I am trying to check where I am doing something wrong
wise-white
wise-whiteOP•8mo ago
If I move from the home page to sign in page it looks like this But when I reload I don't get the duplication anymore and everything works fine but when I click the link to take me to sign in it looks like the sign in is just above the home page
No description
manual-pink
manual-pink•8mo ago
probably a hydration error? can you share the url where this is deployed? ideally a minimal reproducer would be helpful to debug this
wise-white
wise-whiteOP•8mo ago
Okay I am using next-themes when I remove it I can't reproduce any of the behaviour in production so I think that is the culprit Any other libraries I can use for theme
manual-pink
manual-pink•8mo ago
yes thats most likely a hydration error then. check out https://discord.com/channels/719702312431386674/1313219828315721799
manual-pink
manual-pink•8mo ago
GitHub
GitHub - ally-ahmed/tss-blog-starter at nekochan-theme-impl
A blog/portfolio starter project built with TanStack Start. - GitHub - ally-ahmed/tss-blog-starter at nekochan-theme-impl
manual-pink
manual-pink•8mo ago
wise-white
wise-whiteOP•8mo ago
Okay I'm using the new implementation and I'm back to getting the same issue
manual-pink
manual-pink•8mo ago
Error: Can't find theme in localStorage. Make sure you wrap the app with ThemeProvider.
nice cars btw 😄
wise-white
wise-whiteOP•8mo ago
Thanks There are just images from unsplash 😅
manual-pink
manual-pink•8mo ago
oh I had hoped you'd ship me one
wise-white
wise-whiteOP•8mo ago
Where are you getting this error I'm not getting it here
manual-pink
manual-pink•8mo ago
on the first load clear your browser cache or incognito window
wise-white
wise-whiteOP•8mo ago
Can you please try it again I'm not getting it here And I'm sure the app is wrapped with the ThemeProvider
manual-pink
manual-pink•8mo ago
hm did not happen again do you get a hydration error in dev?
wise-white
wise-whiteOP•8mo ago
Yeah
manual-pink
manual-pink•8mo ago
then checkout the diff
wise-white
wise-whiteOP•8mo ago
No description
manual-pink
manual-pink•8mo ago
then the scripts gets executed too late needs to run before hydration we don't have a nice API for this yet unfortunately can you please create github issue so we track this
wise-white
wise-whiteOP•8mo ago
Okay I would do that But is there any solution for this currently?
manual-pink
manual-pink•8mo ago
a hacky solution would be to use this in ssr.tsx
import type { AnyRouter } from "@tanstack/react-router";

/// <reference types="vinxi/types/server" />
import { getRouterManifest } from "@tanstack/start/router-manifest";
import {
createStartHandler,
defaultStreamHandler,

} from "@tanstack/start/server";

import { createRouter } from "./router";

export type HandlerCallback<TRouter extends AnyRouter> = (ctx: {
request: Request;
router: TRouter;
responseHeaders: Headers;
}) => Response | Promise<Response>;

const streamHandler: HandlerCallback<AnyRouter> = (ctx) => {
ctx.router.serverSsr!.injectScript(() => `function initTheme() {
if (typeof localStorage === 'undefined') return

const localTheme = localStorage.getItem('theme')
const preferTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
const resolvedTheme = localTheme === null || localTheme === 'system' ? preferTheme : localTheme

if (localTheme === null) {
localStorage.setItem('theme', 'system')
}
console.log('initTheme', resolvedTheme)

document.documentElement.dataset.theme = resolvedTheme
document.documentElement.style.colorScheme = resolvedTheme
}
console.log('initTheme')

initTheme()`);
return defaultStreamHandler(ctx);
};
export default createStartHandler({
createRouter: () => {
const router = createRouter();
return router;
},
getRouterManifest,
})(streamHandler);
import type { AnyRouter } from "@tanstack/react-router";

/// <reference types="vinxi/types/server" />
import { getRouterManifest } from "@tanstack/start/router-manifest";
import {
createStartHandler,
defaultStreamHandler,

} from "@tanstack/start/server";

import { createRouter } from "./router";

export type HandlerCallback<TRouter extends AnyRouter> = (ctx: {
request: Request;
router: TRouter;
responseHeaders: Headers;
}) => Response | Promise<Response>;

const streamHandler: HandlerCallback<AnyRouter> = (ctx) => {
ctx.router.serverSsr!.injectScript(() => `function initTheme() {
if (typeof localStorage === 'undefined') return

const localTheme = localStorage.getItem('theme')
const preferTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
const resolvedTheme = localTheme === null || localTheme === 'system' ? preferTheme : localTheme

if (localTheme === null) {
localStorage.setItem('theme', 'system')
}
console.log('initTheme', resolvedTheme)

document.documentElement.dataset.theme = resolvedTheme
document.documentElement.style.colorScheme = resolvedTheme
}
console.log('initTheme')

initTheme()`);
return defaultStreamHandler(ctx);
};
export default createStartHandler({
createRouter: () => {
const router = createRouter();
return router;
},
getRouterManifest,
})(streamHandler);

Did you find this page helpful?