How to use Vue with GraphQL

Using Vue with GraphQL provides powerful data fetching capabilities through declarative queries, efficient caching, and real-time subscriptions for modern application development. As the creator of CoreUI with extensive Vue experience since 2014, I’ve implemented GraphQL integrations in numerous enterprise applications for optimized data management and user experiences. The most effective approach involves using GraphQL clients with Vue 3 Composition API to handle queries, mutations, and subscriptions with reactive data management. This method provides type-safe API interactions while maintaining excellent performance through intelligent caching and optimistic updates.

Integrate GraphQL with Vue using composables and reactive queries for efficient data fetching and state management.

import { ref, computed } from 'vue'
import { createClient, gql, defaultExchanges, subscriptionExchange } from '@urql/vue'
import { createClient as createWSClient } from 'graphql-ws'

// GraphQL client setup
const wsClient = createWSClient({
    url: 'ws://localhost:4000/graphql'
})

const client = createClient({
    url: 'http://localhost:4000/graphql',
    exchanges: [
        ...defaultExchanges,
        subscriptionExchange({
            forwardSubscription: (operation) => ({
                subscribe: (sink) => ({
                    unsubscribe: wsClient.subscribe(operation, sink)
                })
            })
        })
    ]
})

// GraphQL queries and mutations
const GET_USERS = gql`
    query GetUsers($limit: Int, $offset: Int) {
        users(limit: $limit, offset: $offset) {
            id
            name
            email
            avatar
            createdAt
        }
        userCount
    }
`

const CREATE_USER = gql`
    mutation CreateUser($input: CreateUserInput!) {
        createUser(input: $input) {
            id
            name
            email
            avatar
        }
    }
`

const USER_SUBSCRIPTION = gql`
    subscription OnUserCreated {
        userCreated {
            id
            name
            email
        }
    }
`

// Vue composable for GraphQL operations
export function useGraphQLUsers() {
    const users = ref([])
    const totalUsers = ref(0)
    const loading = ref(false)
    const error = ref(null)

    const fetchUsers = async (limit = 10, offset = 0) => {
        try {
            loading.value = true
            error.value = null

            const result = await client.query(GET_USERS, {
                limit,
                offset
            }).toPromise()

            if (result.error) {
                throw new Error(result.error.message)
            }

            users.value = result.data.users
            totalUsers.value = result.data.userCount
        } catch (err) {
            error.value = err.message
        } finally {
            loading.value = false
        }
    }

    const createUser = async (userData) => {
        try {
            loading.value = true
            error.value = null

            const result = await client.mutation(CREATE_USER, {
                input: userData
            }).toPromise()

            if (result.error) {
                throw new Error(result.error.message)
            }

            users.value.push(result.data.createUser)
            totalUsers.value += 1

            return result.data.createUser
        } catch (err) {
            error.value = err.message
            throw err
        } finally {
            loading.value = false
        }
    }

    const subscribeToUsers = () => {
        client.subscription(USER_SUBSCRIPTION).subscribe(result => {
            if (result.data?.userCreated) {
                users.value.push(result.data.userCreated)
                totalUsers.value += 1
            }
        })
    }

    return {
        users: computed(() => users.value),
        totalUsers: computed(() => totalUsers.value),
        loading: computed(() => loading.value),
        error: computed(() => error.value),
        fetchUsers,
        createUser,
        subscribeToUsers
    }
}

This code demonstrates comprehensive GraphQL integration with Vue using a modern GraphQL client that handles queries, mutations, and subscriptions through a reusable composable. The setup includes WebSocket support for real-time updates, error handling, loading states, and reactive data management using Vue’s Composition API. The composable pattern provides clean separation of concerns while maintaining type safety and performance optimization through intelligent caching and subscription management.

Best Practice Note:

This is the GraphQL integration pattern we use in CoreUI dashboard applications for real-time data management and optimized API interactions. Implement query fragments for reusable field selections and consider using GraphQL Code Generator for automatic TypeScript type generation from your schema.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author