Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export default defineConfig({
{
link: '/getting-started',
text: 'Getting Started'
},
{
link: '/migration',
text: 'Migration'
}
],
text: 'Guide'
Expand Down
165 changes: 165 additions & 0 deletions packages/docs/migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Migration Guide

This plugin is designed to make migration from **@vue/apollo-composable** effortless.


## Quick Overview
1. Upgrade to **Apollo Client v4**
2. Update imports from `@vue/apollo-composable` → `@vue3-apollo/core`
3. Integrate new **loading tracking system** (optional but recommended)
4. Review **Breaking Changes** and update types or options accordingly


## 1. Migration Steps

### 1.1 Update Apollo Client

Vue3 Apollo requires **Apollo Client v4** or higher.

```bash
npm install @apollo/client@^4
```

```json
{
"@apollo/client": "^4.x.x"
}
```

### 1.2 Update Imports

Simply change imports from `@vue/apollo-composable` to `@vue3-apollo/core`.

**Before:**
```ts
import { useQuery } from '@vue/apollo-composable'
```

**After:**
```ts
import { useQuery, useMutation, useSubscription } from '@vue3-apollo/core'
```

All composables maintain the same API, so migration typically only involves updating import paths.


## 2. Enhanced Loading Tracking

Vue3 Apollo introduces an improved tracking system to monitor loading states globally or per component.

### Example
```ts
import { useQueriesLoading } from '@vue3-apollo/core'

// Track loading of queries in a specific component or scope
const isLoading = useQueriesLoading('dashboard')
```

You can pass an optional **`id`** parameter to share loading states across components.

### Available Helpers
- `useQueryLoading(id?)`
- `useMutationLoading(id?)`
- `useSubscriptionLoading(id?)`
- Global variants: `useGlobalQueryLoading()`, `useGlobalMutationLoading()`, `useGlobalSubscriptionLoading()`


## 3. Breaking Changes

The new `useAsyncQuery` for Nuxt is close to the old one but there are some **notable differences** you should adjust for:

### 1) Positional overloads removed → object options only
**Before (positional):**
```ts
useAsyncQuery(query, variables?, clientId?, context?, options?)
```
**After (object):**
```ts
useAsyncQuery({
query,
variables,
clientId, // optional
context, // optional
})
```
> This simplifies typing and aligns with Apollo `QueryOptions`.

### 2) `useLazyAsyncQuery` removed
Use `useAsyncQuery` with Nuxt `AsyncData` options instead of the dedicated "lazy" variant.

**Before:**
```ts
useLazyAsyncQuery({
query,
variables,
})
```
**After (Nuxt AsyncData):**
```ts
useAsyncQuery(
{
query,
variables,
},
{
lazy: true, // do not block navigation; fetch after route resolves
},
)
```

### 3) `cache` option removed
The old `cache?: boolean` flag is replaced by **Apollo fetch policies**.

**Before:**
```ts
useAsyncQuery({
query,
variables,
cache: true,
})
```
**After:**
```ts
useAsyncQuery({
query,
variables,
fetchPolicy: 'cache-first',
})
```

## 4. Summary
| Feature | Old | New | Notes |
|----------|-----|-----|-------|
| Async Query (SSR) | `useAsyncQuery` from old package | `useAsyncQuery` (object options) | Unified API for Nuxt 4 |
| Lazy Async Query | `useLazyAsyncQuery` | Removed → use `useAsyncQuery` with `{ lazy: true }` | Simplified lazy fetching |
| Query / Mutation / Subscription | `@vue/apollo-composable` | `@vue3-apollo/core` | Same API |
| Global Loading Tracking | ✅ | ✅ | via `useApolloTracker` |
| Component-scoped Loading | ❌ | ✅ | pass `id` to track across scopes |
| Apollo v4 Support | Manual | ✅ | Native |


## 5. Example Migration

**Before:**
```ts
import { useQuery } from '@vue/apollo-composable'
import MY_QUERY from './myQuery.gql'

const { result, loading, error } = useQuery(MY_QUERY)
```

**After:**
```ts
import { useQuery } from '@vue3-apollo/core'
import MY_QUERY from './myQuery.gql'

const { result, loading, error } = useQuery(MY_QUERY)
```

Optionally track loading across components:
```ts
import { useQueriesLoading } from '@vue3-apollo/core'
const isLoading = useQueriesLoading('dashboard')
```

🎉 **Migration complete!** Replace imports, update Apollo Client to v4, and enjoy new global tracking.
52 changes: 52 additions & 0 deletions packages/nuxt/src/runtime/composables/useAsyncQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,65 @@ import { useAsyncData } from 'nuxt/app'
import { hash } from 'ohash'
import { unref } from 'vue'

/**
* Configuration options for useAsyncQuery composable
*
* @template TData - The data type returned from the GraphQL query
* @template TVariables - The type of variables passed to the query
*
* @property {MaybeRefOrGetter<string>} [key] - Unique key for caching query results. If not provided, key will be auto-generated from query and variables
*/
export type UseAsyncQueryOptions<TData = unknown, TVariables extends OperationVariables = OperationVariables> = {
key?: MaybeRefOrGetter<string>
} & ApolloClient.QueryOptions<Optional<TData>, TVariables> & UseBaseOption

/**
* Type helper to prevent type inference in specific cases
* @internal
*/
type NoInfer<T> = [T][T extends any ? 0 : never]

/**
* Type helper to make a type optional (undefined)
* @internal
*/
type Optional<T> = T | undefined

/**
* Composable for executing asynchronous GraphQL queries in Nuxt
*
* Combines Apollo Client with Nuxt's useAsyncData to provide:
* - Server-side rendering (SSR) support
* - Automatic caching with unique keys
* - Loading states and error handling
* - Type-safe with TypeScript
*
* @template DataT - The data type returned from the GraphQL query
* @template TVariables - The type of variables passed to the query
* @template PickKeys - Keys picked from the returned data
* @template DefaultT - Default data type when query is not completed
*
* @param {UseAsyncQueryOptions<DataT, TVariables>} options - Query configuration options including GraphQL query, variables, and Apollo Client options
* @param {AsyncDataOptions<DataT, DataT, PickKeys, DefaultT>} [config] - Configuration options for Nuxt's useAsyncData
*
* @returns {AsyncData<DefaultT | PickFrom<DataT, PickKeys>, ErrorLike | NuxtError | undefined>} Object containing reactive data, pending state, error, and utility functions
*
* @example
* ```typescript
* const { data, pending, error } = await useAsyncQuery({
* query: gql`
* query GetUser($id: ID!) {
* user(id: $id) {
* id
* name
* email
* }
* }
* `,
* variables: { id: '123' }
* })
* ```
*/
export function useAsyncQuery<
DataT = unknown,
TVariables extends OperationVariables = OperationVariables,
Expand Down
Loading