Integrating GraphQL with Next.js

Integrating GraphQL with Next.js

·

3 min read

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:

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.

// 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).

// 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.

// 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).

// 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.

// 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.

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


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!