Implement data fetching with urql and Next.js
Tags: javascript, graphql, nextjs, urql
Published: 2023-07-08 17:54:50

## Urql
[URQL](https://formidable.com/open-source/urql/docs/) is a versatile GraphQL client library which is a simplistic and lightweight alternative to other heavy client libraries such as Apollo or Relay. It can handle content heavy pages through [Document caching](https://formidable.com/open-source/urql/docs/basics/document-caching/) and dynamic and data-heavy apps through [Normalized caching](https://formidable.com/open-source/urql/docs/graphcache/normalized-caching/).

### Installation
Installing `urql` with Next JS is very simple with your choice of package manager. We also need to install `graphql` package as a peer dependency.

```javascript
yarn add urql
or
npm install urql
```
```javascript
yarn add urql graphql
or
npm install graphql
```

### Set up the client

`urql` gives us a `Client` class and we use it to create a new instance of the client with our API endpoint as the url. We create a file `src/graphQL/client.ts` to write the following code.

```javascript
import { createClient } from "urql";

// YOUR API URL
const API_BASE_URL = "http://localhost:3000/graphql";

const client = createClient({
  url: API_BASE_URL,
});

export { client }
```

### Provide the client

We need to wrap our component with `Provider` to use the `client` we previously defined so that every component within it can make use of GraphQL queries. We do this in out `pages/_app.tsx` component.

```javascript
import { Provider as URQLProvider } from "urql";
import { client } from "../graphQL/client";

const App = () => {
  return (
    <URQLProvider value={client}>
      {/* Children component go here */}
    </URQLProvider>
  );
};

export default App;
```

### Run a query
The `useQuery` hook of urql can be used to fetch data from a defined query. Let us first implement a simple query in a separate file `src/graphQL/queries/profile.ts`

```javascript
import { gql } from "urql";

export const GET_PROFILE_QUERY = gql`
  query Profile {
    me {
      id
      username
      createdAt
    }
  }
`;
```
We can now use this query to fetch defined field values with the `useQuery` hook in a component and call this component in our app component.

```javascript
import { useQuery } from "urql";
import { GET_PROFILE_QUERY } from "graphQL/queries/auth";
import { TextLoader } from "ui/components/CustomLoaders";
import ErrorMessage from "ui/components/ErrorMessage";

const Profile = () => {
  // useQuery hook
  const [result, reexecuteQuery] = useQuery({
    query: GET_PROFILE_QUERY,
  });
  const { data, fetching, error } = result;

  // Handle data fetching state with loader component
  if (fetching) return <TextLoader />;
  // Show error in the ui
  if (error) return <ErrorMessage />;

  // Show the received data
  return (
    <div>
      <span>{data.me.username}</span>
      <span>{data.me.createdAt}</span>
    </div>
  );
};

export default Profile;
```
Here, we have implemented a simple query to fetch data with graphQL.
The `fetching` state indicates when data is still being fetched and `error` contains data fetching error from API or any `GraphQLError` and `data` returns the data received from the query call.
The `useQuery` hook returns a tuple and also accepts parameters or variables.