@hitch42/applet 0.1.0-beta.9 → 0.1.1-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client.js +120 -11
- package/dist/_internal/log-context.d.ts +34 -0
- package/dist/_internal/log-context.js +2 -0
- package/dist/_internal/server.js +112 -57
- package/dist/applet.js +12 -12
- package/dist/build-Bh_S5BUv.js +2 -0
- package/dist/{build-CAb26kMY.js → build-CEfFoIZZ.js} +1 -1
- package/dist/{ci-5qWl7lT3.js → ci-BKw14X2h.js} +14 -13
- package/dist/client.d.ts +2 -2
- package/dist/{contract-rP_eV9PK.d.ts → contract-CsUpTBe0.d.ts} +1 -1
- package/dist/{deploy-D_OFJ6-Q.js → deploy-wGYjwXrx.js} +139 -88
- package/dist/{generate-CBPnHoqX.js → generate-BEIYs17x.js} +54 -22
- package/dist/generate-Dox-OYt6.js +2 -0
- package/dist/headers-DkNr9MLJ.js +17 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/{init-tfzwuYnk.js → init-6oGPM46R.js} +10 -15
- package/dist/{load-config-BYSxDVAl.js → load-config-xEdTXs0y.js} +2 -2
- package/dist/log-context-zu8U9Sjm.js +73 -0
- package/dist/{login-C7RKmmTe.js → login-CUx3TmFQ.js} +1 -1
- package/dist/{logs-DgjgAxj2.js → logs-DSjuEN0Q.js} +20 -22
- package/dist/{manifest-DD_SGkS6.d.ts → manifest-C6_F4bL8.d.ts} +5 -1
- package/dist/{manifest-Bp87Uz0a.js → manifest-CJSL9GuC.js} +20 -4
- package/dist/{project-D6XHllmC.js → project-BRZGd6xq.js} +197 -16
- package/dist/query-cache-CXmAyLv3.js +82 -0
- package/dist/react.d.ts +2 -1
- package/dist/react.js +59 -39
- package/dist/{schedules-dhU1yyFr.js → schedules-C8_Svr4h.js} +1 -1
- package/dist/server.d.ts +8 -3
- package/dist/server.js +29 -8
- package/dist/telephony.d.ts +24 -4
- package/dist/telephony.js +135 -16
- package/dist/{variables-Bwnr7oxf.js → variables-DT5RyHdH.js} +13 -13
- package/dist/vite.d.ts +3 -60
- package/dist/vite.js +50 -15
- package/dist/{workflow-engine-MogejNfF.js → workflow-engine-BOTzURKM.js} +1 -7
- package/dist/{workspace-XVtM12ZC.js → workspace-D0dnnlxL.js} +33 -38
- package/package.json +13 -6
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +29 -3
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +8 -0
- package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
- package/scaffold/.agents/skills/hitch-applets/references/records.md +2 -0
- package/scaffold/.agents/skills/hitch-data/SKILL.md +2 -1
- package/scaffold/.agents/skills/hitch-data/references/attributes.md +7 -1
- package/scaffold/.agents/skills/hitch-data/references/limits.md +13 -13
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +3 -2
- package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
- package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
- package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
- package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
- package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
- package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
- package/scaffold/.github/workflows/hitch.yml +1 -1
- package/scaffold/AGENTS.md +2 -2
- package/scaffold/applet/src/client/components/ui/alert.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/button.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/checkbox.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/dialog.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/input-group.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/select.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/sheet.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/spinner.tsx +2 -1
- package/scaffold/applet/src/client/components/ui/tabs.tsx +1 -1
- package/scaffold/applet/src/client/lib/utils.ts +1 -6
- package/scaffold/applet/src/client/styles/globals.css +2 -0
- package/dist/build-BfbTbt_r.js +0 -2
- package/dist/generate-BgepN4-b.js +0 -2
package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lifecycle/ssr-hydration-and-streaming
|
|
3
|
+
description: >
|
|
4
|
+
Use this when implementing SSR, hydration, dehydrate, hydrate,
|
|
5
|
+
HydrationBoundary, TanStack Start, TanStack Router SSR Query, Next.js app
|
|
6
|
+
router, Next.js pages router, React Server Components, SvelteKit, Nuxt,
|
|
7
|
+
SolidStart, Lit SSR, ReactQueryStreamedHydration, or streamedQuery.
|
|
8
|
+
type: lifecycle
|
|
9
|
+
library: TanStack Query
|
|
10
|
+
library_version: "5.101.0"
|
|
11
|
+
requires:
|
|
12
|
+
- lifecycle/setup-query-client-and-providers
|
|
13
|
+
- lifecycle/prefetch-and-remove-request-waterfalls
|
|
14
|
+
sources:
|
|
15
|
+
- TanStack/query:docs/framework/react/guides/ssr.md
|
|
16
|
+
- TanStack/query:docs/framework/react/guides/advanced-ssr.md
|
|
17
|
+
- TanStack/query:docs/framework/react/reference/hydration.md
|
|
18
|
+
- TanStack/query:docs/reference/environmentManager.md
|
|
19
|
+
- TanStack/query:docs/reference/streamedQuery.md
|
|
20
|
+
- TanStack/query:docs/framework/vue/guides/ssr.md
|
|
21
|
+
- TanStack/query:docs/framework/svelte/ssr.md
|
|
22
|
+
- TanStack/query:docs/framework/solid/guides/ssr.md
|
|
23
|
+
- TanStack/query:docs/framework/lit/guides/ssr.md
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query";
|
|
30
|
+
|
|
31
|
+
export async function PostsPage() {
|
|
32
|
+
const queryClient = new QueryClient();
|
|
33
|
+
await queryClient.prefetchQuery({
|
|
34
|
+
queryKey: ["posts"],
|
|
35
|
+
queryFn: async () => [{ id: 1 }],
|
|
36
|
+
});
|
|
37
|
+
return (
|
|
38
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
39
|
+
<Posts />
|
|
40
|
+
</HydrationBoundary>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function Posts() {
|
|
45
|
+
return <p>Hydrated posts render here</p>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Core Patterns
|
|
50
|
+
|
|
51
|
+
### Put TanStack Start and Router first
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
55
|
+
import { createRouter } from "@tanstack/react-router";
|
|
56
|
+
import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
|
|
57
|
+
import { routeTree } from "./routeTree.gen";
|
|
58
|
+
|
|
59
|
+
const queryClient = new QueryClient();
|
|
60
|
+
const router = createRouter({ routeTree, context: { queryClient } });
|
|
61
|
+
|
|
62
|
+
setupRouterSsrQueryIntegration({ router, queryClient });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Use per-request clients
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
69
|
+
|
|
70
|
+
export function createSsrQueryClient() {
|
|
71
|
+
return new QueryClient({
|
|
72
|
+
defaultOptions: { queries: { staleTime: 60_000 } },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Hydrate only prefetched data
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query";
|
|
81
|
+
|
|
82
|
+
export async function Page() {
|
|
83
|
+
const queryClient = new QueryClient();
|
|
84
|
+
await queryClient.prefetchQuery({
|
|
85
|
+
queryKey: ["profile"],
|
|
86
|
+
queryFn: async () => ({ name: "Tanner" }),
|
|
87
|
+
});
|
|
88
|
+
return (
|
|
89
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
90
|
+
<main>Profile</main>
|
|
91
|
+
</HydrationBoundary>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Common Mistakes
|
|
97
|
+
|
|
98
|
+
### CRITICAL RSC renders fetched data twice
|
|
99
|
+
|
|
100
|
+
Wrong:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query";
|
|
104
|
+
|
|
105
|
+
export async function Page() {
|
|
106
|
+
const queryClient = new QueryClient();
|
|
107
|
+
const posts = await queryClient.fetchQuery({
|
|
108
|
+
queryKey: ["posts"],
|
|
109
|
+
queryFn: async () => [{ id: 1 }],
|
|
110
|
+
});
|
|
111
|
+
return (
|
|
112
|
+
<>
|
|
113
|
+
<p>{posts.length}</p>
|
|
114
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
115
|
+
<main>Posts</main>
|
|
116
|
+
</HydrationBoundary>
|
|
117
|
+
</>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Correct:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query";
|
|
126
|
+
|
|
127
|
+
export async function Page() {
|
|
128
|
+
const queryClient = new QueryClient();
|
|
129
|
+
await queryClient.prefetchQuery({
|
|
130
|
+
queryKey: ["posts"],
|
|
131
|
+
queryFn: async () => [{ id: 1 }],
|
|
132
|
+
});
|
|
133
|
+
return (
|
|
134
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
135
|
+
<main>Posts</main>
|
|
136
|
+
</HydrationBoundary>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Server-rendered derived data can desynchronize from client-refetched Query data.
|
|
142
|
+
|
|
143
|
+
Source: TanStack/query:docs/framework/react/guides/advanced-ssr.md
|
|
144
|
+
|
|
145
|
+
### CRITICAL Suspense query not prefetched on server
|
|
146
|
+
|
|
147
|
+
Wrong:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
151
|
+
|
|
152
|
+
export function Posts() {
|
|
153
|
+
const { data } = useSuspenseQuery({
|
|
154
|
+
queryKey: ["posts"],
|
|
155
|
+
queryFn: async () => [{ id: 1 }],
|
|
156
|
+
});
|
|
157
|
+
return <pre>{JSON.stringify(data)}</pre>;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Correct:
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import { HydrationBoundary, QueryClient, dehydrate } from "@tanstack/react-query";
|
|
165
|
+
|
|
166
|
+
export async function Page() {
|
|
167
|
+
const queryClient = new QueryClient();
|
|
168
|
+
await queryClient.prefetchQuery({
|
|
169
|
+
queryKey: ["posts"],
|
|
170
|
+
queryFn: async () => [{ id: 1 }],
|
|
171
|
+
});
|
|
172
|
+
return (
|
|
173
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
174
|
+
<main>Posts</main>
|
|
175
|
+
</HydrationBoundary>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
A suspense query that is not prefetched can fetch on the server, fail to hydrate, then fetch again on the client.
|
|
181
|
+
|
|
182
|
+
Source: TanStack/query:docs/framework/react/guides/ssr.md
|
|
183
|
+
|
|
184
|
+
### HIGH SvelteKit query runs after SSR response
|
|
185
|
+
|
|
186
|
+
Wrong:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { QueryClient } from "@tanstack/svelte-query";
|
|
190
|
+
|
|
191
|
+
export const queryClient = new QueryClient();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Correct:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import { browser } from "$app/environment";
|
|
198
|
+
import { QueryClient } from "@tanstack/svelte-query";
|
|
199
|
+
|
|
200
|
+
export const queryClient = new QueryClient({
|
|
201
|
+
defaultOptions: { queries: { enabled: browser } },
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
SvelteKit SSR needs browser-gated default query execution unless server data is explicitly prefetched.
|
|
206
|
+
|
|
207
|
+
Source: TanStack/query:docs/framework/svelte/ssr.md
|
|
208
|
+
|
|
209
|
+
See also: `compositions/compose-query-with-tanstack-router-and-start` for TanStack-owned SSR routing.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lifecycle/test-query-code
|
|
3
|
+
description: >
|
|
4
|
+
Use this when testing TanStack Query code with isolated QueryClient instances,
|
|
5
|
+
test providers, retry false, cache cleanup, async assertions, hook testing,
|
|
6
|
+
React/Vue/Solid/Angular harnesses, and deterministic query state.
|
|
7
|
+
type: lifecycle
|
|
8
|
+
library: TanStack Query
|
|
9
|
+
library_version: "5.101.0"
|
|
10
|
+
requires:
|
|
11
|
+
- lifecycle/setup-query-client-and-providers
|
|
12
|
+
- core/tune-defaults-freshness-retries-and-refetching
|
|
13
|
+
sources:
|
|
14
|
+
- TanStack/query:docs/framework/react/guides/testing.md
|
|
15
|
+
- TanStack/query:docs/framework/solid/guides/testing.md
|
|
16
|
+
- TanStack/query:docs/framework/vue/guides/testing.md
|
|
17
|
+
- TanStack/query:docs/framework/angular/guides/testing.md
|
|
18
|
+
- TanStack/query:packages/query-core/src/__tests__/queryClient.test.tsx
|
|
19
|
+
- TanStack/query:packages/react-query/src/__tests__/useQuery.test.tsx
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import * as React from "react";
|
|
26
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
27
|
+
|
|
28
|
+
export function createTestWrapper() {
|
|
29
|
+
const queryClient = new QueryClient({
|
|
30
|
+
defaultOptions: { queries: { retry: false } },
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return function TestWrapper(props: { children: React.ReactNode }) {
|
|
34
|
+
return <QueryClientProvider client={queryClient}>{props.children}</QueryClientProvider>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Core Patterns
|
|
40
|
+
|
|
41
|
+
### Create a client per test
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
45
|
+
|
|
46
|
+
export function createTestQueryClient() {
|
|
47
|
+
return new QueryClient({
|
|
48
|
+
defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Await async state
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
57
|
+
|
|
58
|
+
export async function loadTodosForTest() {
|
|
59
|
+
const queryClient = new QueryClient({
|
|
60
|
+
defaultOptions: { queries: { retry: false } },
|
|
61
|
+
});
|
|
62
|
+
return queryClient.fetchQuery({
|
|
63
|
+
queryKey: ["todos"],
|
|
64
|
+
queryFn: async () => [{ id: 1 }],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Clear after direct client tests
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
73
|
+
|
|
74
|
+
export function dispose(queryClient: QueryClient) {
|
|
75
|
+
queryClient.clear();
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Common Mistakes
|
|
80
|
+
|
|
81
|
+
### CRITICAL Shared test client
|
|
82
|
+
|
|
83
|
+
Wrong:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
87
|
+
|
|
88
|
+
export const queryClient = new QueryClient();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Correct:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
95
|
+
|
|
96
|
+
export function createQueryClient() {
|
|
97
|
+
return new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
A shared client leaks cache and mutation state across tests.
|
|
102
|
+
|
|
103
|
+
Source: TanStack/query:docs/framework/react/guides/testing.md
|
|
104
|
+
|
|
105
|
+
### HIGH Retry backoff in tests
|
|
106
|
+
|
|
107
|
+
Wrong:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
111
|
+
|
|
112
|
+
export const queryClient = new QueryClient();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Correct:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
119
|
+
|
|
120
|
+
export const queryClient = new QueryClient({
|
|
121
|
+
defaultOptions: { queries: { retry: false } },
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Default retries delay failure and make tests look hung.
|
|
126
|
+
|
|
127
|
+
Source: TanStack/query:docs/framework/react/guides/testing.md
|
|
128
|
+
|
|
129
|
+
### HIGH Asserting before async success
|
|
130
|
+
|
|
131
|
+
Wrong:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
135
|
+
|
|
136
|
+
const queryClient = new QueryClient();
|
|
137
|
+
const promise = queryClient.fetchQuery({
|
|
138
|
+
queryKey: ["todos"],
|
|
139
|
+
queryFn: async () => [{ id: 1 }],
|
|
140
|
+
});
|
|
141
|
+
console.log(queryClient.getQueryData(["todos"]));
|
|
142
|
+
await promise;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Correct:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
149
|
+
|
|
150
|
+
const queryClient = new QueryClient();
|
|
151
|
+
await queryClient.fetchQuery({
|
|
152
|
+
queryKey: ["todos"],
|
|
153
|
+
queryFn: async () => [{ id: 1 }],
|
|
154
|
+
});
|
|
155
|
+
console.log(queryClient.getQueryData(["todos"]));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Query state is asynchronous; assert after the query promise resolves or the UI wait completes.
|
|
159
|
+
|
|
160
|
+
Source: TanStack/query:docs/framework/react/guides/testing.md
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tanstack-router
|
|
3
|
+
description: Build, review, debug, or test React applications with TanStack Router. Use for route trees, file routes, navigation, search parameters, loaders, guards, SSR, code splitting, and Query integration.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TanStack Router
|
|
8
|
+
|
|
9
|
+
TanStack Router is a type-safe router for React and Solid applications. It provides SWR caching, JSON-first search parameters, file routes, and end-to-end type inference.
|
|
10
|
+
|
|
11
|
+
The router is client-first and isomorphic. Loaders run on the client by default and also run on the server with TanStack Start.
|
|
12
|
+
|
|
13
|
+
## Critical Rules
|
|
14
|
+
|
|
15
|
+
- Preserve inferred Router types. Do not cast or annotate inferred route values.
|
|
16
|
+
- Do not treat loaders as server-only code.
|
|
17
|
+
- Change a file route through its file. Do not edit its generated route path.
|
|
18
|
+
- Regenerate `routeTree.gen.ts` after route file changes.
|
|
19
|
+
- Run type tests and a production build after route structure changes.
|
|
20
|
+
|
|
21
|
+
## Use
|
|
22
|
+
|
|
23
|
+
1. Inspect the installed Router version and framework binding.
|
|
24
|
+
2. Select one primary reference from the domain index.
|
|
25
|
+
3. Read another reference only when a listed tension or cross-reference applies.
|
|
26
|
+
4. Read the React binding reference when the task uses React hooks or components.
|
|
27
|
+
5. Validate generated route files, types, tests, and the production build.
|
|
28
|
+
|
|
29
|
+
## Domain Index
|
|
30
|
+
|
|
31
|
+
### Defining routes
|
|
32
|
+
|
|
33
|
+
- [Set up Router Core](references/router-core/index.md)
|
|
34
|
+
- [Configure route generation](references/router-plugin.md)
|
|
35
|
+
- [Define virtual file routes](references/virtual-file-routes.md)
|
|
36
|
+
- [Use the React binding](references/react-router.md)
|
|
37
|
+
|
|
38
|
+
### Navigating
|
|
39
|
+
|
|
40
|
+
- [Use links, navigation, preloading, and blocking](references/router-core/navigation.md)
|
|
41
|
+
|
|
42
|
+
### Managing URL state
|
|
43
|
+
|
|
44
|
+
- [Validate and transform search parameters](references/router-core/search-params.md)
|
|
45
|
+
- [Use path parameters, splats, and optional parameters](references/router-core/path-params.md)
|
|
46
|
+
|
|
47
|
+
### Loading data
|
|
48
|
+
|
|
49
|
+
- [Use route loaders, cache settings, context, and deferred data](references/router-core/data-loading.md)
|
|
50
|
+
- [Coordinate Router with TanStack Query](references/compositions/router-query.md)
|
|
51
|
+
|
|
52
|
+
### Protecting routes
|
|
53
|
+
|
|
54
|
+
- [Use authentication and route guards](references/router-core/auth-and-guards.md)
|
|
55
|
+
|
|
56
|
+
### Rendering and layout
|
|
57
|
+
|
|
58
|
+
- [Split route code](references/router-core/code-splitting.md)
|
|
59
|
+
- [Handle missing routes, errors, and route masks](references/router-core/not-found-and-errors.md)
|
|
60
|
+
|
|
61
|
+
### Type safety
|
|
62
|
+
|
|
63
|
+
- [Preserve inference and narrow route types](references/router-core/type-safety.md)
|
|
64
|
+
|
|
65
|
+
### Server rendering
|
|
66
|
+
|
|
67
|
+
- [Use SSR, hydration, streaming, and head management](references/router-core/ssr.md)
|
|
68
|
+
|
|
69
|
+
## Failure Mode Inventory
|
|
70
|
+
|
|
71
|
+
| Area | Check for |
|
|
72
|
+
| --------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
73
|
+
| [Route setup](references/router-core/index.md) | Missing Router type registration |
|
|
74
|
+
| [Route setup](references/router-core/index.md) | An uncommitted `routeTree.gen.ts` file |
|
|
75
|
+
| [Route setup](references/router-core/index.md) | Route properties in an order that breaks inference |
|
|
76
|
+
| [Route generation](references/router-plugin.md) | A Router plugin placed after the framework plugin |
|
|
77
|
+
| [Route setup](references/router-core/index.md) | Incorrect `getParentRoute` use in code routes |
|
|
78
|
+
| [Navigation](references/router-core/navigation.md) | Path parameters interpolated into the `to` string |
|
|
79
|
+
| [Navigation](references/router-core/navigation.md) | `useNavigate` used for a clickable element instead of `Link` |
|
|
80
|
+
| [Navigation](references/router-core/navigation.md) | Relative navigation without `from` |
|
|
81
|
+
| [Navigation](references/router-core/navigation.md) | A search object that replaces parameters instead of a search function |
|
|
82
|
+
| [Search parameters](references/router-core/search-params.md) | Zod `.catch()` used instead of the adapter `fallback()` |
|
|
83
|
+
| [Search parameters](references/router-core/search-params.md) | The full search object returned from `loaderDeps` |
|
|
84
|
+
| [Search parameters](references/router-core/search-params.md) | `Date` objects passed as search parameters |
|
|
85
|
+
| [Search parameters](references/router-core/search-params.md) | A parent route without `validateSearch` when inheritance is required |
|
|
86
|
+
| [Path parameters](references/router-core/path-params.md) | Path parameters interpolated into the `to` string |
|
|
87
|
+
| [Path parameters](references/router-core/path-params.md) | `*` used for a splat route instead of `$` |
|
|
88
|
+
| [Path parameters](references/router-core/path-params.md) | Curly braces used for a basic dynamic segment |
|
|
89
|
+
| [Data loading](references/router-core/data-loading.md) | A loader treated as server-only code |
|
|
90
|
+
| [Data loading](references/router-core/data-loading.md) | The default `staleTime` of zero ignored |
|
|
91
|
+
| [Data loading](references/router-core/data-loading.md) | `reset()` used instead of `router.invalidate()` in an error component |
|
|
92
|
+
| [Data loading](references/router-core/data-loading.md) | Missing factory parentheses on `createRootRouteWithContext` |
|
|
93
|
+
| [Data loading](references/router-core/data-loading.md) | React hooks used in `beforeLoad` or `loader` |
|
|
94
|
+
| [Router and Query](references/compositions/router-query.md) | A missing `defaultPreloadStaleTime: 0` setting |
|
|
95
|
+
| [Router and Query](references/compositions/router-query.md) | A module-level `QueryClient` used during SSR |
|
|
96
|
+
| [Router and Query](references/compositions/router-query.md) | An awaited `prefetchQuery` that blocks rendering |
|
|
97
|
+
| [Authentication](references/router-core/auth-and-guards.md) | An authentication check in a component instead of `beforeLoad` |
|
|
98
|
+
| [Authentication](references/router-core/auth-and-guards.md) | A redirect caught without rethrow |
|
|
99
|
+
| [Authentication](references/router-core/auth-and-guards.md) | Conditional rendering of the root route component |
|
|
100
|
+
| [Code splitting](references/router-core/code-splitting.md) | Exported route property functions that prevent code splitting |
|
|
101
|
+
| [Code splitting](references/router-core/code-splitting.md) | An attempt to split the root route |
|
|
102
|
+
| [Code splitting](references/router-core/code-splitting.md) | A split loader that adds a second asynchronous step |
|
|
103
|
+
| [Code splitting](references/router-core/code-splitting.md) | A `Route` import in a split file instead of `getRouteApi` |
|
|
104
|
+
| [Missing routes and errors](references/router-core/not-found-and-errors.md) | The deprecated `NotFoundRoute` API |
|
|
105
|
+
| [Missing routes and errors](references/router-core/not-found-and-errors.md) | `useLoaderData` expected to work in `notFoundComponent` |
|
|
106
|
+
| [Missing routes and errors](references/router-core/not-found-and-errors.md) | A leaf route expected to handle a missing route |
|
|
107
|
+
| [Route masking](references/router-core/not-found-and-errors.md) | A masked URL expected to remain after sharing |
|
|
108
|
+
| [Type safety](references/router-core/type-safety.md) | Type annotations or casts on inferred values |
|
|
109
|
+
| [Type safety](references/router-core/type-safety.md) | An unnarrowed `LinkProps` type |
|
|
110
|
+
| [Type safety](references/router-core/type-safety.md) | A `Link` or `useNavigate` call without `from` narrowing |
|
|
111
|
+
| [SSR](references/router-core/ssr.md) | Browser APIs in loaders without an environment check |
|
|
112
|
+
| [SSR](references/router-core/ssr.md) | Hash fragments used for server-rendered content |
|
|
113
|
+
| [SSR](references/router-core/ssr.md) | Next.js or Remix SSR patterns used with TanStack Router |
|
|
114
|
+
|
|
115
|
+
## Tensions
|
|
116
|
+
|
|
117
|
+
| Tension | Read together | Apply |
|
|
118
|
+
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
119
|
+
| Type safety and fast prototyping | [Router Core](references/router-core/index.md), [type safety](references/router-core/type-safety.md) | Add the `Register` declaration and fix the inferred type. Do not silence the error with a cast. |
|
|
120
|
+
| Client-first loaders and SSR expectations | [Data loading](references/router-core/data-loading.md), [SSR](references/router-core/ssr.md) | Keep loader code safe in each environment where it runs. |
|
|
121
|
+
| Router cache and Query cache | [Data loading](references/router-core/data-loading.md), [Router and Query](references/compositions/router-query.md) | Give data ownership to one cache and prevent duplicate fetches. |
|
|
122
|
+
| Split size and loader performance | [Code splitting](references/router-core/code-splitting.md), [data loading](references/router-core/data-loading.md) | Keep critical loader work out of avoidable split steps. |
|
|
123
|
+
|
|
124
|
+
## Cross-References
|
|
125
|
+
|
|
126
|
+
- Read [type safety](references/router-core/type-safety.md) with [Router Core](references/router-core/index.md). Type registration and route property order control inference.
|
|
127
|
+
- Read [search parameters](references/router-core/search-params.md) with [navigation](references/router-core/navigation.md). The `search` property uses validated search state.
|
|
128
|
+
- Read [search parameters](references/router-core/search-params.md) with [data loading](references/router-core/data-loading.md). `loaderDeps` uses validated search state as cache keys.
|
|
129
|
+
- Read [data loading](references/router-core/data-loading.md) before [Router and Query](references/compositions/router-query.md). The built-in cache affects external cache coordination.
|
|
130
|
+
- Read [data loading](references/router-core/data-loading.md) with [authentication](references/router-core/auth-and-guards.md). `beforeLoad` supplies route context before the loader runs.
|
|
131
|
+
- Read [data loading](references/router-core/data-loading.md) with [code splitting](references/router-core/code-splitting.md). Loader splitting changes request latency.
|
|
132
|
+
- Read [data loading](references/router-core/data-loading.md) with [SSR](references/router-core/ssr.md). SSR changes the loader execution environment.
|
|
133
|
+
- Read [Router and Query](references/compositions/router-query.md) with [SSR](references/router-core/ssr.md). SSR requires per-request cache isolation and hydration.
|
|
134
|
+
- Read [data loading](references/router-core/data-loading.md) with [missing routes and errors](references/router-core/not-found-and-errors.md). Loader errors select route error boundaries.
|