Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap and InnerWrap not properly wrapping router components (@tanstack/solid-start) #3744

Open
timredd opened this issue Mar 11, 2025 · 0 comments

Comments

@timredd
Copy link

timredd commented Mar 11, 2025

Which project does this relate to?

Start

Describe the bug

The Wrap and InnerWrap components (from createTanstackRouter) aren't, well, wrapping the app. In my particular case, this means the QueryClientProvider context is not able to be accessed via useQueryClient, which is how I noticed it. You can see in the below screenshot that the two components get injected as siblings to the main component tree, rather than a part of. Potentially an SSR/hydration issue?

A simple workaround is to just move QueryClientProvider to a route component and pass queryClient there.

Your Example Website or App

https://codesandbox.io/p/devbox/serverless-platform-3fyfd3?file=%2Fsrc%2Froutes%2F__root.tsx%3A11%2C1&workspaceId=ws_Kd4jkuu9beA8EHP9C8SzFs

Steps to Reproduce the Bug or Issue

Setup a router like the following:

// src/router.tsx
import { createTanstackRouter } from '@tanstack/solid-router';
import { QueryClient, QueryClientProvider } from '@tanstack/solid-query';

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

  const router = createTanstackRouter({
    routeTree,
    context: { queryClient },
    defaultPreload: "intent",
    defaultPreloadStaleTime: 0,
    dehydrate: () => ({
      queryClientState: dehydrate(queryClient),
    }),
    hydrate: (dehydrated) => {
      hydrate(queryClient, dehydrated.queryClientState);
    },
    // Issue is here. Also applies to `InnerWrap`
    Wrap: (props) => (
      <QueryClientProvider client={queryClient}>
        {props.children}
      </QueryClientProvider>
    ),
  });

  return router;
}

// src/routes/index.tsx
export const Route = createFileRoute("/")({
  component: RouteComponent,
});

function RouteComponent() {
  // Results in runtime error:
  // `No QueryClient set, use QueryClientProvider to set one`
  const queryClient = useQueryClient();
  ///          ^ undefined
  
  // Rest of component...
}

Expected behavior

Wrap and/or InnerWrap should wrap the router's child components.

Screenshots or Videos

You can see that the Wrap and InnerWrap components exist but aren't in the correct position in the component hierarchy.

Image
the main portion of the component tree is folded under CatchBoundary

Platform

Additional context

Workaround

Very simple workaround, just move the QueryClientProvider into the a route component ie. RootComponent and pass the queryClient in there, either via import or via router context.

// src/routes/__root.tsx

// via import
// import { queryClient } from '../router'

// Typical root route setup
// ...

function RootComponent() {
  // or via context
  const queryClient = Route.useRouteContext({ select: (c) => c.queryClient });

  return (
    <>
        <QueryClientProvider client={queryClient()}>
          <Outlet />
        </QueryClientProvider>
    </>
  )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants