Introducing the new Vue Query client
Tags: frontend, programming, typescript, javascript
Published: 2023-05-12 13:00:00



![VUE FTW](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rn6l93heh187lidyraog.png)

After React and Solid, we now have official Vue support! 🎉.

This new client is built on top of [Vue Query](https://vue-query.tanstack.com/), and brings all the good stuff from WunderGraph to the Vue ecosystem. Query, mutate and subscribe to your WunderGraph API fully typesafe in Vue.

The integration has been built by one of our community members, [Hebilicious](https://twitter.com/its_hebilicious). Thanks Emmanuel, you rock!

## Quick start

```bash
npx create-wundergraph-app my-project --example nuxt
```

## Installation

Let's have a quick look at how to set it up in a Nuxt project and how to use it. (this assumes you already have Nuxt and WunderGraph installed).

Install the Vue Query client:

```bash
npm install @wundergraph/vue-query @tanstack/vue-query
```

## Configuration

Before you can use the hooks, you need to modify your code generation to include the base typescript client.

```typescript
 {% filename="wundergraph.config.ts" %}
// wundergraph.config.ts
configureWunderGraphApplication({
  // ... omitted for brevity
  codeGenerators: [
    {
      templates: [templates.typescript.client],
      // the location where you want to generate the client
      path: './components/generated',
    },
  ],
})
```

Now we need to configure the Vue Query client. We'll create a plugin for this.

```typescript
 {% filename="plugins/vue-query.ts" %}
import type {
  DehydratedState,
  VueQueryPluginOptions,
} from '@tanstack/vue-query'
import {
  VueQueryPlugin,
  QueryClient,
  hydrate,
  dehydrate,
} from '@tanstack/vue-query'
import { useState } from '#app'

import { createHooks } from '@wundergraph/vue-query'
import { createClient, Operations } from '../components/generated/client'

export default defineNuxtPlugin((nuxt) => {
  const vueQueryState = useState<DehydratedState | null>('vue-query')

  const queryClient = new QueryClient({
    defaultOptions: { queries: { staleTime: 5000 } },
  })
  const options: VueQueryPluginOptions = { queryClient }

  nuxt.vueApp.use(VueQueryPlugin, options)

  if (process.server) {
    nuxt.hooks.hook('app:rendered', () => {
      vueQueryState.value = dehydrate(queryClient)
    })
  }

  if (process.client) {
    nuxt.hooks.hook('app:created', () => {
      hydrate(queryClient, vueQueryState.value)
    })
  }

  const client = createClient() // Typesafe WunderGraph client
  const wgraph = createHooks<Operations>(client)
  return {
    provide: {
      wgraph,
    },
  }
})
```

## Usage

### Queries

```typescript 
{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useQuery({
    operationName: 'Dragons',
    input: {
      limit: 1,
    },
  });
  await suspense();
</script>
```

Turn queries into live queries, live queries are refetched on a interval on the WunderGraph server.

```typescript
{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useQuery({
    operationName: 'Dragons',
    input: {
      limit: 1,
    },
    liveQuery: true
  });
  await suspense();
</script>
```

### Subscriptions

Build realtime apps with subscriptions.

```typescript
{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useSubscription({
    operationName: 'Countdown',
    input: {
      from: 1,
    },
  });
  await suspense();
</script>
```

### Mutations

```typescript
 {% filename="pages/index.vue" %}
<script lang="ts" setup>
const {
	$wgraph: { useMutation },
} = useNuxtApp();

const id = ref('1');
const name = ref('Jens');
const bio = ref('Founder of WunderGraph');

const { data, mutate } = useMutation({
	operationName: 'users/update',
});
</script>
```

### Invalidating queries

Let's say we have a query that fetches the current user's profile in one component and we have a form that updates the profile. We can add an `onSuccess` handler to the mutation that calls `queryClient.invalidateQueries` on the `GetProfile` query and trigger a refetch and update the internal React Query cache.

```typescipt
 {% filename="pages/index.vue" %}
<script lang="ts" setup>
import { useQueryClient, useQuery, useMutation } from "@tanstack/vue-query";

// Access QueryClient instance
const queryClient = useQueryClient();

const {
	$wgraph: { useMutation, queryKey },
} = useNuxtApp();

const id = ref('1');
const name = ref('Jens');
const bio = ref('Founder of WunderGraph');

const { data, mutate } = useMutation({
	operationName: 'users/update',
  onSuccess: () => {
    // Invalidate and refetch
    queryClient.invalidateQueries(queryKey({operationName: 'GetProfile'}));
  },
});
</script>
```

Check out the reference and example app below to learn more about the new Vue Query integration.

## Resources

- [Vue Query reference](https://docs.wundergraph.com/docs/clients-reference/vue-query)
- [Nuxt Example](https://docs.wundergraph.com/docs/examples/nuxt)
- [TanStack Vue Query](https://tanstack.com/query/v4/docs/vue/overview)

## Summary

We're very excited to see the community building integrations for WunderGraph. If you have ideas for other integrations, let us know in the comments below or join us on our [Discord server](https://wundergraph.com/discord).