All skills
apollographql avatar

/apollo-client

@cb48e40 official
by Apollo GraphQLapollographql/skills115 stars
13

Guide for building React applications with Apollo Client 4.x. Use this skill when: (1) setting up Apollo Client in a React project, (2) writing GraphQL queries or mutations with hooks, (3) configuring caching or cache policies, (4) managing local state with reactive variables, (5) troubleshooting Apollo Client errors or performance issues.

Use this Skill: https://skilld.dev/gh/apollographql/skills/apollo-client

This session only. Nothing lands on disk.

referencesintegration-react-router.md

≈1.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Apollo Client Integration with React Router Framework Mode

This guide covers integrating Apollo Client in a React Router 7 application with support for modern streaming SSR.

Installation

Install Apollo Client and the React Router integration package:

npm install @apollo/client-integration-react-router @apollo/client graphql rxjs

TypeScript users: For type-safe GraphQL operations, see the TypeScript Code Generation guide.

Setup

Step 1: Create Apollo Configuration

Create an app/apollo.ts file that exports a makeClient function and an apolloLoader:

import { HttpLink, InMemoryCache } from "@apollo/client";
import {
  createApolloLoaderHandler,
  ApolloClient,
} from "@apollo/client-integration-react-router";

// `request` will be available on the server during SSR or in loaders, but not in the browser
export const makeClient = (request?: Request) => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({ uri: "https://your-graphql-endpoint.com/graphql" }),
  });
};

export const apolloLoader = createApolloLoaderHandler(makeClient);

Important: ApolloClient must be imported from @apollo/client-integration-react-router, not from @apollo/client.

Step 2: Reveal Entry Files

Run the following command to create the entry files if they don't exist:

npx react-router reveal

This will create app/entry.client.tsx and app/entry.server.tsx.

Step 3: Configure Client Entry

Adjust app/entry.client.tsx to wrap your app in ApolloProvider:

import { makeClient } from "./apollo";
import { ApolloProvider } from "@apollo/client";
import { StrictMode, startTransition } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router/dom";

startTransition(() => {
  const client = makeClient();
  hydrateRoot(
    document,
    <StrictMode>
      <ApolloProvider client={client}>
        <HydratedRouter />
      </ApolloProvider>
    </StrictMode>
  );
});

Step 4: Configure Server Entry

Adjust app/entry.server.tsx to wrap your app in ApolloProvider during SSR:

import { makeClient } from "./apollo";
import { ApolloProvider } from "@apollo/client";
// ... other imports

export default function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  routerContext: EntryContext
) {
  return new Promise((resolve, reject) => {
    // ... existing code

    const client = makeClient(request);

    const { pipe, abort } = renderToPipeableStream(
      <ApolloProvider client={client}>
        <ServerRouter
          context={routerContext}
          url={request.url}
          abortDelay={ABORT_DELAY}
        />
      </ApolloProvider>,
      {
        [readyOption]() {
          shellRendered = true;
          // ... rest of the handler
        },
        // ... other options
      }
    );
  });
}

Step 5: Add Hydration Helper

Add <ApolloHydrationHelper> to app/root.tsx:

import { ApolloHydrationHelper } from "@apollo/client-integration-react-router";
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <ApolloHydrationHelper>{children}</ApolloHydrationHelper>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

Usage

Using apolloLoader with useReadQuery

You can now use the apolloLoader function to create Apollo-enabled loaders for your routes:

import { gql } from "@apollo/client";
import { useReadQuery } from "@apollo/client/react";
import { useLoaderData } from "react-router";
import type { Route } from "./+types/my-route";
import type { TypedDocumentNode } from "@apollo/client";
import { apolloLoader } from "./apollo";

// TypedDocumentNode definition with types
const GET_USER: TypedDocumentNode<
  { user: { id: string; name: string; email: string } },
  { id: string }
> = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
`;

export const loader = apolloLoader<Route.LoaderArgs>()(({ preloadQuery }) => {
  const userQueryRef = preloadQuery(GET_USER, {
    variables: { id: "1" },
  });

  return {
    userQueryRef,
  };
});

export default function UserPage() {
  const { userQueryRef } = useLoaderData<typeof loader>();
  const { data } = useReadQuery(userQueryRef);

  return (
    <div>
      <h1>{data.user.name}</h1>
      <p>{data.user.email}</p>
    </div>
  );
}

Important: To provide better TypeScript support, apolloLoader is a method that you need to call twice: apolloLoader<LoaderArgs>()(loader)

Multiple Queries in a Loader

You can preload multiple queries in a single loader:

import { gql } from "@apollo/client";
import { useReadQuery } from "@apollo/client/react";
import { useLoaderData } from "react-router";
import type { Route } from "./+types/my-route";
import { apolloLoader } from "./apollo";

// TypedDocumentNode definitions omitted for brevity

export const loader = apolloLoader<Route.LoaderArgs>()(({ preloadQuery }) => {
  const userQueryRef = preloadQuery(GET_USER, {
    variables: { id: "1" },
  });

  const postsQueryRef = preloadQuery(GET_POSTS, {
    variables: { userId: "1" },
  });

  return {
    userQueryRef,
    postsQueryRef,
  };
});

export default function UserPage() {
  const { userQueryRef, postsQueryRef } = useLoaderData<typeof loader>();
  const { data: userData } = useReadQuery(userQueryRef);
  const { data: postsData } = useReadQuery(postsQueryRef);

  return (
    <div>
      <h1>{userData.user.name}</h1>
      <h2>Posts</h2>
      <ul>
        {postsData.posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

Important Considerations

  1. Import ApolloClient from Integration Package: Always import ApolloClient from @apollo/client-integration-react-router, not from @apollo/client, to ensure proper SSR hydration.

  2. TypeScript Support: The apolloLoader function requires double invocation for proper TypeScript type inference: apolloLoader<LoaderArgs>()(loader).

  3. Request Context: The makeClient function receives the Request object during SSR and in loaders, but not in the browser. Use this to set up auth headers or other request-specific configuration.

  4. Streaming SSR: The integration fully supports React's streaming SSR capabilities. Place Suspense boundaries strategically for optimal user experience.

  5. Cache Hydration: The ApolloHydrationHelper component ensures that data loaded on the server is properly hydrated on the client, preventing unnecessary refetches.

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive reference and integration guide for Apollo Client 4.x in React applications. No security vulnerabilities, malicious code, or adversarial patterns were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    4/14 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at cb48e40. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 5 months ago
What it can do
Runs commands
metadata
{
  "author": "apollographql",
  "version": "1.0.0"
}
All 1 allowed tools
Bash(npm:*) Bash(npx:*) Bash(node:*) Read Write Edit Glob Grep
Other metadata
compatibility
React 18+, React 19 (Suspense/RSC). Works with Next.js, Vite, CRA, and other React frameworks.
  • React
  • TypeScript
  • apollo-client
  • graphql
  • state-management
  • caching
  • queries
  • mutations
  • suspense

README badge

README badge for apollographql/skills/apollo-client

Guides for building React applications with Apollo Client 4.x, covering queries, mutations, caching, local state, and Suspense integration. Targets React 18+, React 19, Next.js, Vite, and other React frameworks with patterns for client-side apps, server-side rendering, and modern data fetching.

Generated from the current SKILL.md.

Does this skill work with React Server Components and Next.js App Router?
Yes. The skill includes integration guides for Next.js App Router with React Server Components, and supports React 19 with Suspense.
What Apollo Client version does this skill target?
Apollo Client 4.x specifically. The skill does not cover v3 or earlier patterns.
Does this skill cover TypeScript code generation for GraphQL operations?
Yes. The skill includes a reference section on TypeScript Code Generator setup for type-safe operations.
Can I use this skill to configure caching and optimize performance?
Yes. The skill covers InMemoryCache configuration, typePolicies, fetchPolicy strategies, and performance patterns including @defer and @stream.
What frameworks does this skill support beyond client-side React?
It includes integration guides for Next.js App Router, React Router 7 with streaming SSR, and TanStack Start, in addition to client-side apps built with Vite or Create React App.

Generated from the current SKILL.md. These answers refresh after source changes.