# Integrating GraphQL with Next.js

GraphQL has become a popular choice for managing API requests, thanks to its flexibility and efficiency in querying data. Combining GraphQL with Next.js allows developers to build powerful, scalable applications. In this guide, we’ll explore how to integrate GraphQL with Next.js using Apollo Client for fetching data.

---

## Why Use GraphQL with Next.js?

* **Flexible Queries**: Fetch only the data you need.
    
* **Efficient Data Fetching**: Reduce over-fetching and under-fetching of data.
    
* **Strong Typing**: GraphQL schemas provide clear definitions for APIs.
    
* **Great for Modern Apps**: Works seamlessly with Next.js’s data-fetching methods.
    

---

## Setting Up Apollo Client in Next.js

Apollo Client is a popular GraphQL client that simplifies data fetching and state management. 

### Step 1: Install Dependencies

Install Apollo Client and supporting libraries:

```typescript
npm install @apollo/client graphql
```

### Step 2: Set Up Apollo Client

Create an `apollo-client.ts` file in your project to configure the Apollo Client.

```typescript
// src/apollo-client.ts
import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://your-graphql-endpoint.com/graphql', // Replace with your GraphQL endpoint
  cache: new InMemoryCache(),
});

export default client;
```

### Step 3: Provide Apollo Client to Your App

Wrap your application with the ApolloProvider in the `layout.tsx` file or a custom `_app.tsx` (if using the pages directory).

```typescript
// src/app/layout.tsx
import { ApolloProvider } from '@apollo/client';
import client from '../apollo-client';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ApolloProvider client={client}>{children}</ApolloProvider>
      </body>
    </html>
  );
}
```

---

## Fetching Data with Apollo Client

Apollo Client can fetch data on the client side or during server rendering in Next.js.

### Client-Side Fetching

Use Apollo’s `useQuery` hook to fetch data in a React component.

```typescript
// src/app/products/page.tsx
import { gql, useQuery } from '@apollo/client';

const GET_PRODUCTS = gql`
  query GetProducts {
    products {
      id
      name
      price
    }
  }
`;

export default function ProductsPage() {
  const { loading, error, data } = useQuery(GET_PRODUCTS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>Products</h1>
      <ul>
        {data.products.map((product: any) => (
          <li key={product.id}>{product.name} - ${product.price}</li>
        ))}
      </ul>
    </div>
  );
}
```

### Server-Side Rendering (SSR)

Fetch data during server rendering using Apollo Client in Next.js’s `getServerSideProps` or `generateMetadata` (for app directory).

```typescript
// src/app/products/page.tsx
import { gql } from '@apollo/client';
import client from '../../apollo-client';

const GET_PRODUCTS = gql`
  query GetProducts {
    products {
      id
      name
      price
    }
  }
`;

export default async function ProductsPage() {
  const { data } = await client.query({ query: GET_PRODUCTS });

  return (
    <div>
      <h1>Products</h1>
      <ul>
        {data.products.map((product: any) => (
          <li key={product.id}>{product.name} - ${product.price}</li>
        ))}
      </ul>
    </div>
  );
}
```

---

## Advanced Features

### Using Mutations

Mutations allow you to modify server-side data. Use the `useMutation` hook for client-side updates.

```typescript
// src/app/products/AddProduct.tsx
import { gql, useMutation } from '@apollo/client';

const ADD_PRODUCT = gql`
  mutation AddProduct($name: String!, $price: Float!) {
    addProduct(name: $name, price: $price) {
      id
      name
    }
  }
`;

export default function AddProduct() {
  const [addProduct] = useMutation(ADD_PRODUCT);

  const handleAddProduct = async () => {
    await addProduct({ variables: { name: 'New Product', price: 99.99 } });
    alert('Product added!');
  };

  return <button onClick={handleAddProduct}>Add Product</button>;
}
```

### Optimistic UI Updates

Apollo Client supports optimistic updates to provide a smoother user experience.

```typescript
await addProduct({
  variables: { name: 'New Product', price: 99.99 },
  optimisticResponse: {
    addProduct: {
      id: 'temp-id',
      name: 'New Product',
      __typename: 'Product',
    },
  },
});
```

---

## Useful Links

* [Apollo Client Documentation](https://www.apollographql.com/blog/next-js-getting-started)
    
* [GraphQL Official Website](https://graphql.org/)
    
* [Next.js Documentation](https://www.nextjs.org)
    

---

## Conclusion

Integrating GraphQL with Next.js using Apollo Client enables developers to build modern, efficient, and flexible applications. Whether fetching data on the client or server, Apollo Client’s features simplify the process and enhance the user experience. Start exploring the power of GraphQL in your Next.js projects today!
