TanStack / router

🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
https://tanstack.com/router
MIT License
8.27k stars 661 forks source link

Getting "Target container is not a DOM element" when preloading long data via Tanstack Query #2533

Open ondrejvelisek opened 1 month ago

ondrejvelisek commented 1 month ago

Which project does this relate to?

Start

Describe the bug

Hi,

hope it is not a duplicate. :)

Facts

When using TanStack Query with preloading from Routes loader, TanStack Start stringify query response data and sends it together with HTML document. Just at the end of <head> section.

JavaScript bundle with React component tree and hydrating functionality is at the begining of <head> section.

<body> with <div id="root"> comes last after <head>.

Problem

When data are very long, JS bundle is executed before data are streamed to a browser. And therefore before <div id="root"> is present.

Im getting this in browser console:

Uncaught Error: Minified React error #299; visit https://react.dev/errors/299 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at Wc.hydrateRoot (client-DIQpUtaV.js:49:33157)
    at client-DIQpUtaV.js:142:3802

At least, I guess this is what is happening. :)

Related code:

~__root.tsx

...
export const Route = createRootRouteWithContext<{
  queryClient: QueryClient;
}>()({
  component: RootComponent,
  meta: () => [ ...

2024/~_providers.$.tsx (child page)

  loader: async ({ context }) => {
    await context.queryClient.ensureQueryData(expensesDataQueryOptions()); // very long data
  },

client.tsx

/// <reference types="vinxi/types/client" />
import { hydrateRoot } from "react-dom/client";
import { StartClient } from "@tanstack/start";
import { createRouter } from "./router";

const router = createRouter();

hydrateRoot(document.getElementById("root")!, <StartClient router={router} />);

router.tsx

import { QueryClient } from "@tanstack/react-query";
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
import { routerWithQueryClient } from "@tanstack/react-router-with-query";
import { routeTree } from "./routeTree.gen";

export function createRouter() {
  const queryClient = new QueryClient();

  const router = createTanStackRouter({
    routeTree,
    context: { queryClient },
    defaultPreload: "intent",
  });

  return routerWithQueryClient(router, queryClient);
}

declare module "@tanstack/react-router" {
  interface Register {
    router: ReturnType<typeof createRouter>;
  }
}

ssr.tsx

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

import { createRouter } from "./router";

export default createStartHandler({
  createRouter,
  getRouterManifest,
})(defaultStreamHandler);

Your Example Website or App

https://github.com/ondrejvelisek/peoples-budget

Steps to Reproduce the Bug or Issue

  1. Open link https://peoples-budget.vercel.app/2024/odvetvi
  2. Wait
  3. See error in console (In some cases it works. I guess it depends on network conditions or caching?)

Expected behavior

I expect page got hydrated and react runs on client.

Screenshots or Videos

Image

Platform

Additional context

No response

schiller-manuel commented 1 month ago

can you please provide exact steps to reproduce? which link should be clicked?

ondrejvelisek commented 1 month ago

Hi. Sure. Its here: https://peoples-budget.vercel.app/2024/odvetvi If any more info is needed, let me know.

Also updated original post to include this.

tannerlinsley commented 1 month ago

This could be due to the useQuery that happens before the root is rendered into the shell. I'll have a closer look in a bit.

schiller-manuel commented 1 month ago

@ondrejvelisek can you please provide a minimal complete example? your application is quite big, so narrowing it down would help a lot for debugging.

ondrejvelisek commented 1 month ago

@schiller-manuel Sure. There you go:

Link to deployed vercel: https://peoples-budget-git-tanstart-bug-eb5c0b-ondrejveliseks-projects.vercel.app/

Branch on github: https://github.com/ondrejvelisek/peoples-budget/tree/tanstart-bug-min-example

This is basically your Tanstack Start + Tanstack query example with bigger data.

I noticed on local dev server it works just fine.

schiller-manuel commented 1 month ago

so this can't be reproduced locally?

ondrejvelisek commented 1 month ago

No. Locally it seems working. Only production build is affected.

ondrejvelisek commented 1 month ago

Not sure why though. Maybe it is due to a network conditions or something related to production build?

tannerlinsley commented 1 week ago

Could you please try this again with the latest release? I fixed some thing with out of order streaming.

paulm17 commented 1 week ago

So the good news is that. A smaller subset of my UI lib works.

UI Subset

The bad news, is that the full version of the UI lib still has the same issue.

The key difference, is that generating the styles is computationally more heavy. So the time in transit in generating the styles is far far longer and incidentally what's missing is the actual styles. So hopefully this narrows down the issue for the team.

Full UI

My repo of Start:

https://github.com/paulm17/tanstack-start

npm i npm run dev

Aslam97 commented 1 week ago

@paulm17 Try render it to document instead of root

Before

hydrateRoot(document.getElementById("root")!, <StartClient router={router} />);

Image

After

hydrateRoot(document!, <StartClient router={router} />);

Image

And if you get hydration warnings:

Warning: Extra attributes from the server: class,style Error Component Stack

add suppressHydrationWarning={true} to html.

paulm17 commented 1 week ago

@Aslam97 Thanks. Sometimes I just need another pair of eyes. Even though I went through the app folder of the 2nd repo. I completely missed the document change. Which the first repo had, hence why it worked.

Many thanks for letting me know.

schiller-manuel commented 6 days ago

@ondrejvelisek can you please check if this issue still exist in the latest release?

ondrejvelisek commented 5 days ago

On it.

ondrejvelisek commented 5 days ago

Unfortunately no. The error is still the same. See: https://peoples-budget-git-tanstart-bug-eb5c0b-ondrejveliseks-projects.vercel.app/

Current deps versions: https://github.com/ondrejvelisek/peoples-budget/blob/tanstart-bug-min-example/package.json

ondrejvelisek commented 2 days ago

I have to correct myself. The error is different. I forgot to update hydration root. In new version of TanStart requires whole document to be thrown into hydrate root. Sorry for confusion.

So new error looks like this: Image