T
TanStack3w ago
broad-brown

Hydration fails silently ?

Hi, I'm trying out the latest tanstack start and I'm facing a weird issue. My route is defined like this:
export const Route = createFileRoute("/projects")({
component: Gallery,
loader: async () => {
const projects = await getAllProjectsWithImagesServer();
return { projects };
},
});
export const Route = createFileRoute("/projects")({
component: Gallery,
loader: async () => {
const projects = await getAllProjectsWithImagesServer();
return { projects };
},
});
And in my Gallery component, I'm getting the loaderData and displaying a list of project. When I click on a project, it's supposed to open a model with project details, but the onClick never get triggered. I trying debugging it and I never see any console.log I put in, appart from:
export default function Gallery() {
const { projects } = useLoaderData({ from: "/projects" });
const [selectedProject, setSelectedProject] =
useState<ProjectWithImages | null>(null);

const isHydrated = useHydrated();

console.log("isHydrated", isHydrated);

useEffect(() => {
console.log(isHydrated);
}, [isHydrated]);

return (
<div className="py-20 px-4">
...
export default function Gallery() {
const { projects } = useLoaderData({ from: "/projects" });
const [selectedProject, setSelectedProject] =
useState<ProjectWithImages | null>(null);

const isHydrated = useHydrated();

console.log("isHydrated", isHydrated);

useEffect(() => {
console.log(isHydrated);
}, [isHydrated]);

return (
<div className="py-20 px-4">
...
I can see the first isHydrated false in the terminal when my dev server is launched. I just don't get why I doesn't see it set to true in my useEffect, and more importantly why I'm not getting any interaction with my page. I don't see any error messages in the console... Could you guys help me out please ?
2 Replies
rare-sapphire
rare-sapphire3w ago
i had this when migrating my app from next to start, it was server code leaking into the client. say you have this:
async function getData() {
return fetch(...);
}

const $getData = createServerFn().handler(async () => {
return await getData();
})
async function getData() {
return fetch(...);
}

const $getData = createServerFn().handler(async () => {
return await getData();
})
getData was leaking and silently breaking hydration. if you must co-locate the function, wrapping it in createServerOnlyFn fixes it
const getData = createServerOnlyFn(async () => fetch(...));

const $getData = createServerFn().handler(async () => {
return await getData();
})
const getData = createServerOnlyFn(async () => fetch(...));

const $getData = createServerFn().handler(async () => {
return await getData();
})
other-emerald
other-emerald2w ago
Just to confirm, you are rendering Scripts on your root route, right? And what is getAllProjectsWithImagesServer? How do you declare it? loaders are executed on both client and server

Did you find this page helpful?