This article's content
Generate client side GraphQL hooks for URQL

Assume you have your GraphQL server running on localhost:3333, you have your React app setup and you are now at the point at which you want to request and manipulate data from your GraphQL server via URQL.

You set up your React app to use URQL client with devtools enabled and adding a potential token from your localStorage to every request:

import { devtoolsExchange } from "@urql/devtools";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { createClient, defaultExchanges, Provider } from "urql";

import App from "./app/app";

const client = createClient({
  url: "http://localhost:3333/graphql",
  exchanges: [devtoolsExchange, ...defaultExchanges],
  fetchOptions: () => {
    const token = localStorage.getItem("token");
    return {
      headers: { authorization: token ? `Bearer ${token}` : "" },
    };
  },
});

const root = createRoot(document.getElementById("root") as HTMLElement);
root.render(
  <StrictMode>
    <Provider value={client}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </StrictMode>,
);

Next you add a Container component which executes your request:

import { FC, HTMLAttributes } from "react";

const TestNotificationQuery = `
  query {
    testNotifications {
      content
      subject
      _id
    }
  }
`;

export const NotificationsTestPageContainer: FC<Props> = () => {
  const [result] = useQuery({
    query: TestNotificationQuery
  });

  const { data, fetching, error } = result;

  if (fetching) return <p>Loading...</p>;
  if (error) return <p>Oh no... {error.message}</p>;

  return (
    <NotificationsTestPage testNotifications={data.testNotifications} />
  );
};

That’s the manual way to do it, but be could do a little better: We want to extract our GQL and also want to generate the hook. We start by installing and setting up the code generator from the-guild.dev:

yarn add graphql
yarn add -D typescript
yarn add -D @graphql-codegen/cli
yarn add -D @graphql-codegen/client-preset
yarn add -D @graphql-codegen/typescript-urql

and create:

overwrite: true
schema: "http://localhost:3333/graphql"
documents: "./libs/whatever/src/lib/**/*.graphql"
generates:
  libs/types/src/generated/graphql.tsx:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-urql"
    config:
      withHooks: true

Extract the GQL to its own file

query getTestNotifications {
  testNotifications {
    content
    subject
    _id
  }
}

To generate the code to ./libs/whatever/src/lib/*/.graphql you execute this:

graphql-codegen --config codegen.yml

Now you can use the generated hook instead of the old one:

// const [result] = useQuery({
//   query: TestNotificationQuery
// });

const [result] = useGetTestNotificationsQuery();

About Author

Mathias Bothe To my job profile

I am Mathias, born 40 years ago in Heidelberg, Germany. Today I am living in Munich and Stockholm. I am a passionate IT freelancer with more than 16 years experience in programming, especially in developing web based applications for companies that range from small startups to the big players out there. I am founder of bosy.com, creator of the security service platform BosyProtect© and initiator of several other software projects.