{"id":18116921,"url":"https://github.com/platypusrex/nextjs-apollo-client","last_synced_at":"2025-04-14T13:44:45.100Z","repository":{"id":40252390,"uuid":"485197179","full_name":"platypusrex/nextjs-apollo-client","owner":"platypusrex","description":"Integrate Apollo client in a Next.js application","archived":false,"fork":false,"pushed_at":"2023-01-07T05:59:29.000Z","size":582,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T02:53:03.516Z","etag":null,"topics":["apollo-client","getserversideprops","getstaticprops","graphql","nextjs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/nextjs-apollo-client","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/platypusrex.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-25T02:27:12.000Z","updated_at":"2023-03-24T23:55:37.000Z","dependencies_parsed_at":"2023-02-06T13:30:35.730Z","dependency_job_id":null,"html_url":"https://github.com/platypusrex/nextjs-apollo-client","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platypusrex%2Fnextjs-apollo-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platypusrex%2Fnextjs-apollo-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platypusrex%2Fnextjs-apollo-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platypusrex%2Fnextjs-apollo-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/platypusrex","download_url":"https://codeload.github.com/platypusrex/nextjs-apollo-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248890390,"owners_count":21178421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo-client","getserversideprops","getstaticprops","graphql","nextjs"],"created_at":"2024-11-01T04:17:17.696Z","updated_at":"2025-04-14T13:44:45.045Z","avatar_url":"https://github.com/platypusrex.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"left\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/7143612/166865041-706b38dd-6cfb-465f-8dbe-61000481025a.png\" width=\"100\" height=\"100\" style=\"display: inline\" /\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/7143612/166865059-5a2d8f22-e20b-48a8-9d37-9b7474cd853f.png\" width=\"auto\" height=\"100\" style=\"display: inline\" /\u003e\n\u003c/p\u003e\n\n\n# nextjs-apollo-client\n[![npm Package](https://img.shields.io/npm/v/nextjs-apollo-client.svg)](https://www.npmjs.org/package/nextjs-apollo-client)\n[![License](https://img.shields.io/npm/l/nextjs-apollo-client.svg)](https://github.com/platypusrex/nextjs-apollo-client/blob/master/LICENSE)\n[![Coverage Status](https://coveralls.io/repos/github/platypusrex/nextjs-apollo-client/badge.svg?branch=master)](https://coveralls.io/github/platypusrex/nextjs-apollo-client?branch=master)\n![CI](https://github.com/platypusrex/nextjs-apollo-client/workflows/CI/badge.svg)\n\nSimple integration of Apollo client in a Next.js application. Easy setup with a simple\nbut powerful API that can adapt to any use case.\n\n### Installation\nnpm\n```shell\nnpm i nextjs-apollo-client @apollo/client graphql\n```\nor yarn\n```shell\nyarn add nextjs-apollo-client @apollo/client graphql\n```\n\n### Setup\nThe example below is the bare minimum requirements to get started. For more info about the API and usage continue\nreading. For more advanced usage check out the [example](https://github.com/platypusrex/nextjs-apollo-client/tree/master/example).\n\n1. **Create a new instance of `NextApolloClient`**\n```ts\n// lib/apollo/index.ts\nexport const { getServerSideApolloProps, useApolloClient } = new NextApolloClient({\n  client: { uri: 'http://mygraph.com/graphql' }\n});\n```\n\n2. **Add the Apollo provider to `_app.tsx` passing in the client**\n```tsx\n// _app.tsx\nimport type { AppProps } from 'next/app'\nimport { ApolloProvider } from '@apollo/client';\nimport { useApolloClient } from '../lib/apollo';\n\nconst App = ({ Component, pageProps }: AppProps) =\u003e {\n  const client = useApolloClient(pageProps);\n  return (\n    \u003cApolloProvider client={client}\u003e\n      \u003cComponent {...pageProps} /\u003e\n    \u003c/ApolloProvider\u003e\n  );\n};\n\nexport default App\n```\n\n3. **Utilize the generated `getServerSideApolloProps` to start hydrating data for your pages**\n```tsx\nimport type { NextPage } from 'next'\nimport { useQuery } from '@apollo/client';\nimport { getServerSideApolloProps } from '../lib/apollo';\nimport { USERS_QUERY } from '../gql';\n\nconst Home: NextPage = () =\u003e {\n  const { data } = useQuery(USERS_QUERY);\n\n  return (\n    \u003cdiv\u003e\n      ...rest\n    \u003c/div\u003e\n  )\n}\n\nexport const getServerSideProps = getServerSideApolloProps({\n  hydrateQueries: (ctx) =\u003e [\n    { query: USER_QUERY, variables: { id: ctx.query.id } }\n  ],\n});\n\nexport default Home;\n```\n\n**Note:**\nThe `nextjs-apollo-client` package works really well with [next-merge-props](https://github.com/platypusrex/next-merge-props).\nEspecially if you have multiple abstractions for Next.js server side data fetching functions.\n\n```tsx\nimport type { NextPage } from 'next'\nimport { useQuery } from '@apollo/client';\nimport { mergeProps } from 'next-merge-props';\nimport { getServerSideAuthProps } from '../lib/auth';\nimport { getServerSideApolloProps } from '../lib/apollo';\nimport { USERS_QUERY } from '../gql';\n\nconst Home: NextPage = () =\u003e {\n  const { data } = useQuery(USERS_QUERY);\n\n  return (\n    \u003cdiv\u003e\n      ...rest\n    \u003c/div\u003e\n  )\n}\n\nexport const getServerSideProps = mergeProps(\n  getServerSideAuthProps,\n  getServerSideApolloProps({\n    hydrateQueries: (ctx) =\u003e [\n      { query: USER_QUERY, variables: { id: ctx.query.id } }\n    ],\n  })\n);\n\nexport default Home;\n```\n\n### NextApolloClient\n\n#### Options\nBelow is a table that represents the structure of that `NextApolloClient` options object.\n\n| **Property** | **Type**                                                                                                                                       | **Required** |\n|--------------|------------------------------------------------------------------------------------------------------------------------------------------------| --- |\n| client       | [ApolloClientConfig](https://github.com/platypusrex/nextjs-apollo-client/blob/e7bff6af8b0c90aea015db3ef3ebd99c6379493d/src/types/index.ts#L40) | yes |\n| hydrationMap | [QueryHydrationMap](https://github.com/platypusrex/nextjs-apollo-client/blob/e7bff6af8b0c90aea015db3ef3ebd99c6379493d/src/types/index.ts#L83)  | no (recommended) |\n\n```ts\nexport interface NextApolloClientOptions {\n  client: ApolloClientConfig;\n  hydrationMap?: QueryHydrationMap;\n}\n```\n\n`client`\n\nThe only required option when creating an instance of `NextApolloClient`. Accepts a partial Apollo client config. For a complete list of available via partial config visit\nthe link to the types above.\n\n**Partial Config:**\n```ts\nexport const { getServerSideApolloProps, useApolloClient } = new NextApolloClient({\n  client: { uri: 'http://mygraph.com/graphql' },\n});\n```\n\nYou can also pass in a function that returns an instance of `ApolloClient` which allows complete control of the Apollo\nclient setup. The function also gives you access to the current client cache state and [Context](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#context-parameter)\nobject from Next.js.\n\n**Apollo client:**\n```ts\nexport const { getServerSideApolloProps, useApolloClient } = new NextApolloClient({\n  client: (initialState, headers) =\u003e\n    new ApolloClient({\n      ssrMode: typeof window === 'undefined',\n      cache: new InMemoryCache().restore(initialState),\n      link: new HttpLink({\n        uri: 'http://mygraph.com/graphql',\n        headers,\n      }),\n    }),\n});\n```\n\n`hydrationMap`\n\nYou can optionally pass in a hydration map. Once you have generated a hydration you can simply reference any key from\nyour map in the `getServerSideApolloProps` function to hydrate that page with any query in the hydration map.\n\nThe `nextjs-apollo-client` package includes a util to that you will need to use to generate the map: `generateHydrationMap`.\nTo get autocompletion for your hydration map, you can provide the instance of `NextApolloClient` with the hydration map\ngeneric.\n\n1. **Generate the hydration map**\n\nThe `generateHydrationMap` function accepts a key/value pair. The key you use will also be the string you reference to\nhydrate queries. The value is a function that provides access to the Next.js [Context](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#context-parameter)\nobject and must return a [QueryOptions](https://github.com/apollographql/apollo-client/blob/c7f268d1c36cfebdb64abdb0640a546f146e4e26/src/core/watchQueryOptions.ts#L53) object. \n```ts\n// hydration map\nconst hydrationMap = generateHydrationMap({\n  user: (ctx): QueryOptions\u003cUserQueryVariables, UserQuery\u003e =\u003e ({\n    query: USER_QUERY,\n    variables: { id: ctx.query.userId as string }\n  }),\n  users: (): QueryOptions\u003cUsersQueryVariables, UsersQuery\u003e =\u003e ({ query: USERS_QUERY }),\n});\n```\n2. **Pass the hydration map to the `NextApolloClient`**\n\nNow that you've generated the map, pass it into your `NextApolloClient` instance and provide the hydration map\ngeneric for autocompletion.\n\n```ts\nexport const { getServerSideApolloProps, useApolloClient } = new NextApolloClient\u003c\n  typeof hydrationMap\n\u003e({\n  hydrationMap,\n  client: { uri: 'http://mygraph.com/graphql' },\n});\n```\n\n3. **Utilize your hydration map from `getServerSideApolloProps`**\n\nNow you're ready to go! Now you can reference any query in your map via a string via autocompletion. \n\n```ts\nexport const getServerSideProps = getServerSideApolloProps({\n  hydrateQueries: ['users'],\n});\n```\n\n### getServerSideApolloProps\n\nThe `NextApolloClient` instance exposes a public method called `getServerSideApolloProps`. This is the function \nthat should be used to hydrate any Next.js page component with data.\n\n#### Args\nBelow is a table that describes the accepted arguments.\n\n| **Property**        | **Type**                                                                                                                                                                                                 | **Required**                                                |\n|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|\n| hydrateQueries      | [HydrateQueries\u003cTHydrationMap\u003e](https://github.com/platypusrex/nextjs-apollo-client/blob/e7bff6af8b0c90aea015db3ef3ebd99c6379493d/src/types/index.ts#L73)                                                | no (if not provided all queries will be made on the client) |\n| onClientInitialized | [ClientInitFn\u003cTProps\u003e](https://github.com/platypusrex/nextjs-apollo-client/blob/e7bff6af8b0c90aea015db3ef3ebd99c6379493d/src/types/index.ts#L74)                                                         | no                                                          |\n| onHydrationComplete | [(results: HydrationResponse\u003cTHydrationMap\u003e) =\u003e ServerSidePropsResult\u003cTProps\u003e](https://github.com/platypusrex/nextjs-apollo-client/blob/ad5af151c15f32205c5cb71e3d2cbcbfa6c6361c/src/types/index.ts#L72) | no                                                          |\n\n```ts\nexport interface GetServerSideApolloPropsOptions\u003c\n  THydrationMap extends QueryHydrationMap,\n  THydrationMapKeys = any,\n  TProps = Record\u003cstring, any\u003e\n\u003e {\n  hydrateQueries?: HydrateQueries\u003cTHydrationMapKeys\u003e;\n  onClientInitialized?: (\n    ctx: GetServerSidePropsContext,\n    apolloClient: ApolloClient\u003cNormalizedCacheObject\u003e\n  ) =\u003e ServerSidePropsResult\u003cTProps\u003e;\n  onHydrationComplete?: (\n    results: HydrationResponse\u003cTHydrationMap\u003e\n  ) =\u003e ServerSidePropsResult\u003cTProps\u003e;\n}\n```\n\n`hydrateQueries`\n\nThis argument is not required, but it is required if you want to actually hydrate data on the server. There are a couple \nof different ways `hydrateQueries` can be used.\n\n1. **Use with a hydration map**\n\nIf you have generated and provided `NextApolloClient` with a hydration map, you can simply reference your queries via map keys.\n\n```ts\nexport const getServerSideProps = getServerSideApolloProps({\n  hydrateQueries: ['users'],\n});\n```\n\n2. **Use with `QueryOptions` array**\n\nIf your already familiar with Apollo client and have ever used `refetchQueries` as a side effect of mutation, this should\nfeel familiar. Accepts a function that provides the Next.js [Context](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#context-parameter)\nobject and must return an array of [QueryOptions](https://github.com/apollographql/apollo-client/blob/c7f268d1c36cfebdb64abdb0640a546f146e4e26/src/core/watchQueryOptions.ts#L53)\nobjects.\n\n```ts\nexport const getServerSideProps = getServerSideApolloProps({\n  hydrateQueries: [\n    { query: USERS_QUERY }\n  ],\n});\n\n// or as a function\n\nexport const getServerSideProps = getServerSideApolloProps({\n  hydrateQueries: (ctx) =\u003e [\n    { query: USER_QUERY, variables: { id: ctx.query.id } }\n  ],\n});\n```\n\n`onClientInitialized`\n\nThe `getServerSideApolloProps` function also exposes a couple of callbacks that allow you to hook into different lifecycles \nof the function. The `onClientInitialized` callback does not assist with hydration but can still hydrate data. In fact,\nit's basically an escape hatch that supports a wide variety of use cases.\n\n* **Mutation operation run on the server**\n\nNot a common use case, but if you need to do it you should do it here. A return is not required, but you can provide the \nsame [return value](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#getserversideprops-return-values)\nexpected in any Next.js `getServerSideProps` function.\n\n```ts\nexport const getServerSideProps = getServerSideApolloProps\u003cPageProps\u003e({\n  hydrateQueries: ['users'],\n  onClientInitialized: async (ctx, apolloClient) =\u003e {\n    const result = await apolloClient.mutate({\n      mutation: MY_MUTATION,\n      variables: {\n        id: ctx.query.id\n      }\n    });\n\n    return { props: { result } }\n  },\n})\n```\n\n`onHydrationComplete`\n\nThe second and last callback option is `onHydrationComplete`. This is used in conjunction with `hydrateQueries` and should\nbe more commonly used than `onClientInitialized`. The callback is run after any queries from `hydrateQueries` are run and\nreturns either the result of any hydration operation or errors from each query. Results for hydrated operations are mapped\nto there operation name. If you have provided the hydration map generic to your instance of `NextApolloClient`, you\nwill get proper auto-completion for any of your hydrated operations.\n\nA return is again not required, but you can provide the\nsame [return value](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#getserversideprops-return-values)\nexpected in any Next.js `getServerSideProps` function.\n\n```ts\ninterface PageProps {\n  userId?: string; \n}\n\nexport const getServerSideProps = getServerSideApolloProps\u003cPageProps\u003e({\n  hydrateQueries: ['user'],\n  onHydrationComplete: ({ user, errors }) =\u003e {\n    const currentUser = user?.data.user;\n    \n    if (errors.length) {\n      return { notFound: true };\n    }\n\n    if (!currentUser) {\n      return {\n        redirect: {\n          destination: '/',\n          permanent: false,\n        }\n      }\n    }\n\n    return {\n      props: { userId: currentUser.id },\n    };\n  }\n});\n```\n\n### useApolloClient\n\nThe only other public method returned from a `NextApolloClient` instance is `useApolloClient`. This react hook has only\none use case and that's to provide the client to Apollo client's context provider. The only argument passed to the hook \nare the `pageProps` associated with the Next.js [_app](https://nextjs.org/docs/advanced-features/custom-app) component.\n\n```tsx\nimport type { AppProps } from 'next/app'\nimport { ApolloProvider } from '@apollo/client';\nimport { useApolloClient } from '../lib/apollo';\n\nconst App = ({ Component, pageProps }: AppProps) =\u003e {\n  const client = useApolloClient(pageProps);\n  return (\n    \u003cApolloProvider client={client}\u003e\n      \u003cComponent {...pageProps} /\u003e\n    \u003c/ApolloProvider\u003e\n  );\n};\n\nexport default App\n```\n\n### Contributors\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n\n## LICENSE\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplatypusrex%2Fnextjs-apollo-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplatypusrex%2Fnextjs-apollo-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplatypusrex%2Fnextjs-apollo-client/lists"}