Skip to content

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

Open
@timredd

Description

@timredd

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>
    </>
  )
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions