Skip to content

Commit af8450f

Browse files
authored
Merge pull request #6 from guendev/add-migration-doc
feat: document migration steps and enhance `useAsyncQuery` API in Nuxt
2 parents 4ce7782 + e2b677d commit af8450f

File tree

3 files changed

+221
-0
lines changed

3 files changed

+221
-0
lines changed

packages/docs/.vitepress/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export default defineConfig({
3636
{
3737
link: '/getting-started',
3838
text: 'Getting Started'
39+
},
40+
{
41+
link: '/migration',
42+
text: 'Migration'
3943
}
4044
],
4145
text: 'Guide'

packages/docs/migration.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Migration Guide
2+
3+
This plugin is designed to make migration from **@vue/apollo-composable** effortless.
4+
5+
6+
## Quick Overview
7+
1. Upgrade to **Apollo Client v4**
8+
2. Update imports from `@vue/apollo-composable``@vue3-apollo/core`
9+
3. Integrate new **loading tracking system** (optional but recommended)
10+
4. Review **Breaking Changes** and update types or options accordingly
11+
12+
13+
## 1. Migration Steps
14+
15+
### 1.1 Update Apollo Client
16+
17+
Vue3 Apollo requires **Apollo Client v4** or higher.
18+
19+
```bash
20+
npm install @apollo/client@^4
21+
```
22+
23+
```json
24+
{
25+
"@apollo/client": "^4.x.x"
26+
}
27+
```
28+
29+
### 1.2 Update Imports
30+
31+
Simply change imports from `@vue/apollo-composable` to `@vue3-apollo/core`.
32+
33+
**Before:**
34+
```ts
35+
import { useQuery } from '@vue/apollo-composable'
36+
```
37+
38+
**After:**
39+
```ts
40+
import { useQuery, useMutation, useSubscription } from '@vue3-apollo/core'
41+
```
42+
43+
All composables maintain the same API, so migration typically only involves updating import paths.
44+
45+
46+
## 2. Enhanced Loading Tracking
47+
48+
Vue3 Apollo introduces an improved tracking system to monitor loading states globally or per component.
49+
50+
### Example
51+
```ts
52+
import { useQueriesLoading } from '@vue3-apollo/core'
53+
54+
// Track loading of queries in a specific component or scope
55+
const isLoading = useQueriesLoading('dashboard')
56+
```
57+
58+
You can pass an optional **`id`** parameter to share loading states across components.
59+
60+
### Available Helpers
61+
- `useQueryLoading(id?)`
62+
- `useMutationLoading(id?)`
63+
- `useSubscriptionLoading(id?)`
64+
- Global variants: `useGlobalQueryLoading()`, `useGlobalMutationLoading()`, `useGlobalSubscriptionLoading()`
65+
66+
67+
## 3. Breaking Changes
68+
69+
The new `useAsyncQuery` for Nuxt is close to the old one but there are some **notable differences** you should adjust for:
70+
71+
### 1) Positional overloads removed → object options only
72+
**Before (positional):**
73+
```ts
74+
useAsyncQuery(query, variables?, clientId?, context?, options?)
75+
```
76+
**After (object):**
77+
```ts
78+
useAsyncQuery({
79+
query,
80+
variables,
81+
clientId, // optional
82+
context, // optional
83+
})
84+
```
85+
> This simplifies typing and aligns with Apollo `QueryOptions`.
86+
87+
### 2) `useLazyAsyncQuery` removed
88+
Use `useAsyncQuery` with Nuxt `AsyncData` options instead of the dedicated "lazy" variant.
89+
90+
**Before:**
91+
```ts
92+
useLazyAsyncQuery({
93+
query,
94+
variables,
95+
})
96+
```
97+
**After (Nuxt AsyncData):**
98+
```ts
99+
useAsyncQuery(
100+
{
101+
query,
102+
variables,
103+
},
104+
{
105+
lazy: true, // do not block navigation; fetch after route resolves
106+
},
107+
)
108+
```
109+
110+
### 3) `cache` option removed
111+
The old `cache?: boolean` flag is replaced by **Apollo fetch policies**.
112+
113+
**Before:**
114+
```ts
115+
useAsyncQuery({
116+
query,
117+
variables,
118+
cache: true,
119+
})
120+
```
121+
**After:**
122+
```ts
123+
useAsyncQuery({
124+
query,
125+
variables,
126+
fetchPolicy: 'cache-first',
127+
})
128+
```
129+
130+
## 4. Summary
131+
| Feature | Old | New | Notes |
132+
|----------|-----|-----|-------|
133+
| Async Query (SSR) | `useAsyncQuery` from old package | `useAsyncQuery` (object options) | Unified API for Nuxt 4 |
134+
| Lazy Async Query | `useLazyAsyncQuery` | Removed → use `useAsyncQuery` with `{ lazy: true }` | Simplified lazy fetching |
135+
| Query / Mutation / Subscription | `@vue/apollo-composable` | `@vue3-apollo/core` | Same API |
136+
| Global Loading Tracking | ✅ | ✅ | via `useApolloTracker` |
137+
| Component-scoped Loading | ❌ | ✅ | pass `id` to track across scopes |
138+
| Apollo v4 Support | Manual | ✅ | Native |
139+
140+
141+
## 5. Example Migration
142+
143+
**Before:**
144+
```ts
145+
import { useQuery } from '@vue/apollo-composable'
146+
import MY_QUERY from './myQuery.gql'
147+
148+
const { result, loading, error } = useQuery(MY_QUERY)
149+
```
150+
151+
**After:**
152+
```ts
153+
import { useQuery } from '@vue3-apollo/core'
154+
import MY_QUERY from './myQuery.gql'
155+
156+
const { result, loading, error } = useQuery(MY_QUERY)
157+
```
158+
159+
Optionally track loading across components:
160+
```ts
161+
import { useQueriesLoading } from '@vue3-apollo/core'
162+
const isLoading = useQueriesLoading('dashboard')
163+
```
164+
165+
🎉 **Migration complete!** Replace imports, update Apollo Client to v4, and enjoy new global tracking.

packages/nuxt/src/runtime/composables/useAsyncQuery.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,65 @@ import { useAsyncData } from 'nuxt/app'
1414
import { hash } from 'ohash'
1515
import { unref } from 'vue'
1616

17+
/**
18+
* Configuration options for useAsyncQuery composable
19+
*
20+
* @template TData - The data type returned from the GraphQL query
21+
* @template TVariables - The type of variables passed to the query
22+
*
23+
* @property {MaybeRefOrGetter<string>} [key] - Unique key for caching query results. If not provided, key will be auto-generated from query and variables
24+
*/
1725
export type UseAsyncQueryOptions<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
1826
key?: MaybeRefOrGetter<string>
1927
} & ApolloClient.QueryOptions<Optional<TData>, TVariables> & UseBaseOption
28+
29+
/**
30+
* Type helper to prevent type inference in specific cases
31+
* @internal
32+
*/
2033
type NoInfer<T> = [T][T extends any ? 0 : never]
2134

35+
/**
36+
* Type helper to make a type optional (undefined)
37+
* @internal
38+
*/
2239
type Optional<T> = T | undefined
2340

41+
/**
42+
* Composable for executing asynchronous GraphQL queries in Nuxt
43+
*
44+
* Combines Apollo Client with Nuxt's useAsyncData to provide:
45+
* - Server-side rendering (SSR) support
46+
* - Automatic caching with unique keys
47+
* - Loading states and error handling
48+
* - Type-safe with TypeScript
49+
*
50+
* @template DataT - The data type returned from the GraphQL query
51+
* @template TVariables - The type of variables passed to the query
52+
* @template PickKeys - Keys picked from the returned data
53+
* @template DefaultT - Default data type when query is not completed
54+
*
55+
* @param {UseAsyncQueryOptions<DataT, TVariables>} options - Query configuration options including GraphQL query, variables, and Apollo Client options
56+
* @param {AsyncDataOptions<DataT, DataT, PickKeys, DefaultT>} [config] - Configuration options for Nuxt's useAsyncData
57+
*
58+
* @returns {AsyncData<DefaultT | PickFrom<DataT, PickKeys>, ErrorLike | NuxtError | undefined>} Object containing reactive data, pending state, error, and utility functions
59+
*
60+
* @example
61+
* ```typescript
62+
* const { data, pending, error } = await useAsyncQuery({
63+
* query: gql`
64+
* query GetUser($id: ID!) {
65+
* user(id: $id) {
66+
* id
67+
* name
68+
* email
69+
* }
70+
* }
71+
* `,
72+
* variables: { id: '123' }
73+
* })
74+
* ```
75+
*/
2476
export function useAsyncQuery<
2577
DataT = unknown,
2678
TVariables extends OperationVariables = OperationVariables,

0 commit comments

Comments
 (0)