diff --git a/packages/solid-router/src/Match.tsx b/packages/solid-router/src/Match.tsx index a6db669e11e..3860858a95d 100644 --- a/packages/solid-router/src/Match.tsx +++ b/packages/solid-router/src/Match.tsx @@ -77,18 +77,26 @@ export const Match = (props: { routeId: string }) => { ? ((route.options as RootRouteOptions).shellComponent ?? SafeFragment) : SafeFragment + const ResolvedSuspenseBoundary = () => + routeOptions().wrapInSuspense === false ? SafeFragment : Solid.Suspense + + const renderPendingComponentFallback = () => { + if (routeOptions().wrapInSuspense === false) { + return undefined + } + if (process.env.NODE_ENV !== 'production') { + return renderInNonRouteComponentContext( + () => , + 'pendingComponent', + ) + } + return + } + const MatchContent = () => ( { - if (process.env.NODE_ENV !== 'production') { - return renderInNonRouteComponentContext( - () => , - 'pendingComponent', - ) - } - return - })()} + fallback={renderPendingComponentFallback()} > @@ -97,20 +105,15 @@ export const Match = (props: { routeId: string }) => { return ( - { // Data-only SSR renders the inner fallback on the server, so // avoid adding an extra suspense fallback on the client. if (shouldSkipSuspenseFallback()) { return undefined } - if (process.env.NODE_ENV !== 'production') { - return renderInNonRouteComponentContext( - () => , - 'pendingComponent', - ) - } - return + return renderPendingComponentFallback() })()} > { - + {renderScrollRestoration?.(router, route)} diff --git a/packages/solid-router/tests/Matches.test.tsx b/packages/solid-router/tests/Matches.test.tsx index 7bece830bbb..a7e3e6da3a5 100644 --- a/packages/solid-router/tests/Matches.test.tsx +++ b/packages/solid-router/tests/Matches.test.tsx @@ -155,6 +155,37 @@ test('should show pendingComponent of root route', async () => { expect(await rendered.findByTestId('root-content')).toBeInTheDocument() }) +test('wrapInSuspense false prevents route pendingComponent suspense fallback', async () => { + const gate = createControlledPromise() + const history = createMemoryHistory({ initialEntries: ['/posts'] }) + const root = createRootRoute({ + component: () => , + }) + const postsRoute = createRoute({ + getParentRoute: () => root, + path: '/posts', + wrapInSuspense: false, + pendingComponent: () =>
Loading
, + loader: () => gate, + component: () =>
Posts content
, + }) + + const router = createRouter({ + routeTree: root.addChildren([postsRoute]), + history, + defaultPendingMs: 0, + }) + + render(() => ) + + await waitFor(() => expect(router.state.status).toBe('pending')) + expect(screen.queryByTestId('posts-pending')).not.toBeInTheDocument() + + gate.resolve() + + expect(await screen.findByText('Posts content')).toBeInTheDocument() +}) + test('useMatchRoute follows superseding pending locations', async () => { const aGate = createControlledPromise() const bGate = createControlledPromise()