Introduction

So I recently ran into a nasty bug where urql, the GraphQL client I was using, seemed broken. Turned out I messed up the order of my exchanges. And I want to prevent others from making this mistake. :)

What are exchanges?

Exchanges are basically middleware. For those not really familiar with middleware in this context, middleware is a piece of software which every request goes through. So you could for example have middleware which will add an arbitrary HTTP header to every request.

How do I add these exchanges to my urql config?

You can add these to your “createClient” function. Here is an example:

import {createClient, dedupExchange, fetchExchange, cacheExchange} from 'urql';

const client = createClient({
    url: 'http://localhost:3000/graphql',
    exchanges: [dedupExchange, cacheExchange, fetchExchange],
});

Now by default, urql already uses the exchanges listed above. So you don’t have to add these manually. It is however very important to note, once you define the exchanges, the defaults don’t apply anymore.

Where I went wrong

So the issue I had was the following. I was using urql in a Next.js application which used SSR (more about that here) and urql has a very nice separate package for Next.js which makes SSR very easy. Now I went ahead and put the “ssrExchange” at the end like this:

import {dedupExchange, cacheExchange, fetchExchange} from '@urql/core';

import {withUrqlClient} from 'next-urql';

export default withUrqlClient(
    ssrExchange => ({
        url: 'http://localhost:3000/graphql',
        exchanges: [dedupExchange, cacheExchange, fetchExchange, ssrExchange],
    }),
    {ssr: true} // Enables server-side rendering using `getInitialProps`
)(Index);

Which is wrong because it should be like this:

import {dedupExchange, cacheExchange, fetchExchange} from '@urql/core';

import {withUrqlClient} from 'next-urql';

export default withUrqlClient(
    ssrExchange => ({
        url: 'http://localhost:3000/graphql',
        exchanges: [dedupExchange, cacheExchange, ssrExchange, fetchExchange],
    }),
    {ssr: true} // Enables server-side rendering using `getInitialProps`
)(Index);

So the “fetchExchange” and the “ssrExchange” should be swapped. This took me a while to find out and this broke my application to the point where it wouldn’t fetch data anymore.

Read more

Most of this information and examples I got from the urql documentation. Don’t make the same mistake as me and read it thoroughly! ;)