From bf57191a9274b12ba3a86a3af159cd9ccf4ae77f Mon Sep 17 00:00:00 2001 From: Ben Younes <2910651+ousamabenyounes@users.noreply.github.com> Date: Thu, 10 Sep 2026 16:33:41 +0000 Subject: [PATCH] fix(solid-query): await SSR status reads --- .changeset/curried-query-ssr.md | 5 + .../src/__tests__/fixtures/ssr-entry.tsx | 91 +++++++++++++ .../solid-query/src/__tests__/ssr.test.ts | 123 ++++++++++++++++++ packages/solid-query/src/useBaseQuery.ts | 9 +- 4 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 .changeset/curried-query-ssr.md create mode 100644 packages/solid-query/src/__tests__/fixtures/ssr-entry.tsx create mode 100644 packages/solid-query/src/__tests__/ssr.test.ts diff --git a/.changeset/curried-query-ssr.md b/.changeset/curried-query-ssr.md new file mode 100644 index 00000000000..de6258761ff --- /dev/null +++ b/.changeset/curried-query-ssr.md @@ -0,0 +1,5 @@ +--- +'@tanstack/solid-query': patch +--- + +Wait for curried queries before rendering Solid query status branches on the server. diff --git a/packages/solid-query/src/__tests__/fixtures/ssr-entry.tsx b/packages/solid-query/src/__tests__/fixtures/ssr-entry.tsx new file mode 100644 index 00000000000..abc650f19e6 --- /dev/null +++ b/packages/solid-query/src/__tests__/fixtures/ssr-entry.tsx @@ -0,0 +1,91 @@ +import { Match, Suspense, Switch } from 'solid-js' +import { renderToStringAsync } from 'solid-js/web' +import { + QueryClient, + QueryClientProvider, + queryOptions, + useQuery, +} from '../../index' + +const QUERY_NAME = 'shell-data' +const QUERY_SLUG = '/' +export const expectedQueryResult = `ok: ${QUERY_SLUG}` +export const initialQueryResult = 'initial data' +export const successLabel = 'Success:' + +export function getCoverage() { + return Reflect.get(globalThis, '__VITEST_COVERAGE__') +} + +export async function render() { + const queryClient = new QueryClient() + let queryFnCalls = 0 + const getOptions = (slug: string) => + queryOptions({ + queryKey: [QUERY_NAME, slug], + queryFn: () => { + queryFnCalls += 1 + return Promise.resolve(`ok: ${slug}`) + }, + }) + + function Page() { + const query = useQuery(() => getOptions(QUERY_SLUG)) + + return ( + + PENDING + ERROR + + {successLabel} {query.data} + + + ) + } + + try { + const markup = await renderToStringAsync(() => ( + + + + + + )) + + return { markup, queryFnCalls } + } finally { + queryClient.clear() + } +} + +export async function renderWithInitialData() { + const queryClient = new QueryClient() + let queryFnCalls = 0 + + function Page() { + const query = useQuery(() => ({ + queryKey: [QUERY_NAME, 'initial'], + queryFn: () => { + queryFnCalls += 1 + return Promise.resolve(expectedQueryResult) + }, + initialData: initialQueryResult, + })) + + return query.isSuccess ? `${successLabel} ${query.data}` : 'PENDING' + } + + try { + const markup = await renderToStringAsync(() => ( + + + + + + )) + + return { markup, queryFnCalls } + } finally { + queryClient.clear() + } +} diff --git a/packages/solid-query/src/__tests__/ssr.test.ts b/packages/solid-query/src/__tests__/ssr.test.ts new file mode 100644 index 00000000000..cae861bb732 --- /dev/null +++ b/packages/solid-query/src/__tests__/ssr.test.ts @@ -0,0 +1,123 @@ +/** @vitest-environment node */ +// cspell:ignore instrumenter + +import { createRequire } from 'node:module' +import { fileURLToPath } from 'node:url' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { createServer } from 'vite' +import solid from 'vite-plugin-solid' +import type { Plugin, ViteDevServer } from 'vite' +import type * as SsrEntry from './fixtures/ssr-entry' + +const PACKAGE_ROOT = fileURLToPath(new URL('../..', import.meta.url)) +const SSR_ENTRY_PATH = '/src/__tests__/fixtures/ssr-entry.tsx' +const USE_BASE_QUERY_PATH = fileURLToPath( + new URL('../useBaseQuery.ts', import.meta.url), +) +const SCRIPT_TAG = '