In the previous article, we generated type safe GraphQL composables from .graphql
files to be used in our VueJS frontend code. Under the hood, the generated functions rely on the @urql/vue
client, which should be configured first before attempting to access our GraphQL operations.
Configuring @urql/vue with a Nuxt3 plugin
To get started, we can provide a basic @urql/vue
client with a plugin in plugins/urql.ts
:
import urql from "@urql/vue";
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
export default defineNuxtPlugin((nuxtApp) => {
const { graphqlApiURL } = useRuntimeConfig();
nuxtApp.vueApp.use(urql, {
url: graphqlApiURL,
});
});
We provide graphqlApiURL
as a public runtime configuration inside nuxt.config.ts
:
publicRuntimeConfig: {
graphqlApiURL: process.env.GRAPHQL_API_URL || "http://localhost:3000/api/graphql",
}
We could try to determine the API URL based on Nuxt options at build or run time, but it's so much easier to define it explicitly.
Setting up the SSR exchange
When executing queries in a page and/or component(s), the fetched results can be combined and serialized in the page payload sent by the server, then rehydrated by the client upon rendering.
To achieve this, we'll need to override urql
's default exchanges by adding the configured SSR exchange at the proper index in the array.
The relevant code for setting this up looks like this:
// ...
import urql, { cacheExchange, dedupExchange, fetchExchange, ssrExchange } from "@urql/vue";
// ...
// Create SSR exchange
const ssr = ssrExchange({
isClient: process.client,
});
// Extract SSR payload once app is rendered on the server
if (process.server) {
nuxtApp.hook("app:rendered", () => {
nuxtApp.payload?.data && (nuxtApp.payload.data.urql = ssr.extractData());
});
}
// Restore SSR payload once app is created on the client
if (process.client) {
nuxtApp.hook("app:created", () => {
nuxtApp.payload?.data && ssr.restoreData(nuxtApp.payload.data.urql);
});
}
// Custom exchanges
const exchanges = [dedupExchange, cacheExchange, ssr, fetchExchange];
// ...
The exchanges
array is then passed to urql
's options to override the default ones.
I'm not 100% sure about the server/client payload handling code above but it works (there might be some Nuxt helpers for achieving this in a simpler way).
Bonus: Configuring the devtools exchange
It can be useful to debug urql
with its official devtools. Let's add it to our dependencies:
yarn add -D @urql/devtools
We can then prepend it to our custom exchanges in plugins/urql.ts
:
import { devtoolsExchange } from "@urql/devtools";
// ...
// Devtools exchange
if (nuxtApp._legacyContext?.isDev) {
exchanges.unshift(devtoolsExchange);
}
// ...
And voilà, our app should now expose debug events in the devtools panel, provided the extension is properly installed in your browser.
Using the generated operations
Since our generated operations can be auto-imported (see the previous article), executing our { hello }
query is as simple as this:
<script setup lang="ts">
const { data } = await useHelloQuery();
</script>
<template>
<div id="front-page" class="prose">
<h1>{{ data?.hello || "Nuxt3 ❤️ GraphQL" }}</h1>
</div>
</template>
How amazing is that? Thanks to the <script setup>
syntax and auto-importing, one line of TypeScript is all it takes to execute our generated query operation and access the result with full type safety!
What about mutations (and subscriptions)?
Using generated mutation operations isn't very different than using queries, the main difference being that the mutation isn't executed automatically. Instead, we have to use the executeMutation
method on the result object returned from our generated composable, i.e. useSomeMutation
.
As for subscriptions, we'll need to configure some kind of transport to use them. This will be the subject of an upcoming article in this exciting series!
For more information, please refer to the @urql/vue
documentation on mutations and subscriptions.
Top comments (2)
Thank you! I've been going crazy with buggy GraphQL clients for Nuxt 3 and this solution with
@urql/vue
just works flawlessly.Thanks for the kind words! You can check out my latest Nuxt / GraphQL / Prisma fullstack project at github.com/lewebsimple/nuxt-graphq...