router icon indicating copy to clipboard operation
router copied to clipboard

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

Open ondrejvelisek opened this issue 1 year ago • 8 comments

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

  • OS: macOS
  • Browser: Chrome
  • Version: 129.0.6668.90 (Official Build) (arm64)

Additional context

No response

ondrejvelisek avatar Oct 13 '24 19:10 ondrejvelisek

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

schiller-manuel avatar Oct 13 '24 20:10 schiller-manuel

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.

ondrejvelisek avatar Oct 14 '24 05:10 ondrejvelisek

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.

tannerlinsley avatar Oct 14 '24 19:10 tannerlinsley

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

schiller-manuel avatar Oct 17 '24 21:10 schiller-manuel

@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.

ondrejvelisek avatar Oct 18 '24 15:10 ondrejvelisek

so this can't be reproduced locally?

schiller-manuel avatar Oct 18 '24 16:10 schiller-manuel

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

ondrejvelisek avatar Oct 18 '24 16:10 ondrejvelisek

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

ondrejvelisek avatar Oct 18 '24 16:10 ondrejvelisek

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

tannerlinsley avatar Nov 17 '24 20:11 tannerlinsley

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

paulm17 avatar Nov 17 '24 21:11 paulm17

@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.

Aslam97 avatar Nov 18 '24 09:11 Aslam97

@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.

paulm17 avatar Nov 18 '24 10:11 paulm17

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

schiller-manuel avatar Nov 19 '24 18:11 schiller-manuel

On it.

ondrejvelisek avatar Nov 20 '24 18:11 ondrejvelisek

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 avatar Nov 20 '24 19:11 ondrejvelisek

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

ondrejvelisek avatar Nov 23 '24 18:11 ondrejvelisek