{"id":197,"date":"2021-05-26T15:42:40","date_gmt":"2021-05-26T21:42:40","guid":{"rendered":"https:\/\/developers.wpengine.com\/blog\/?p=197"},"modified":"2023-04-19T08:53:49","modified_gmt":"2023-04-19T14:53:49","slug":"apollo-client-cache-rehydration-in-next-js","status":"publish","type":"post","link":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/","title":{"rendered":"Apollo Client Cache Rehydration in Next.js"},"content":{"rendered":"\n<p><a target=\"_blank\" href=\"https:\/\/www.apollographql.com\/docs\/react\/\" rel=\"noreferrer noopener\">Apollo Client<\/a>&nbsp;is a popular GraphQL client that can cache the results of your queries, among many other features. If you have an entirely client-side rendered (CSR) front-end app and want to do all your data fetching in the browser, you can simply start off with an empty Apollo Client cache and populate it with data as GraphQL requests execute.<\/p>\n\n\n\n<p>But what if you want to use server-side rendering (SSR), static site generation (SSG), or incremental static regeneration (ISR), though? How can you fetch data ahead of time on the server? Can the Apollo Client&#8217;s cache initialize with that data on the client so that your queries don&#8217;t need to be rerun?<\/p>\n\n\n\n<p>Thankfully, there is a way to fetch data on the server, populate Apollo Client&#8217;s cache, send that cache data to the client, and use it to &#8220;rehydrate&#8221; or initialize Apollo Client&#8217;s cache in the browser. Cache rehydration gives the benefits of SSR\/SSG\/ISR (a fully rendered HTML document on the initial page load, great SEO, etc.). Best of all, you still have the data in Apollo Client&#8217;s cache. This prevents your app from making unnecessary network requests for data you already have.<\/p>\n\n\n\n<p>In this blog post, we&#8217;ll cover how to set up Apollo Client cache rehydration in a Next.js app.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Setup<\/h2>\n\n\n\n<p>Before setting up cache rehydration, fulfill the following prerequisites:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Clone down the repo to your machine: <a href=\"https:\/\/github.com\/kellenmace\/apollo-client-cache-rehydration-in-next-js\">https:\/\/github.com\/kellenmace\/apollo-client-cache-rehydration-in-next-js<\/a><\/li><li>Run <code>npm install<\/code> (or <code>yarn<\/code>) to install the project&#8217;s dependencies.<\/li><li>Create a <code>.env.local<\/code> file in the root directory with this variable defined: <code>NEXT_PUBLIC_WORDPRESS_API_URL=http:\/\/my-local-site.local\/graphql<\/code>. Swap out <code>http:\/\/my-local-site.local<\/code> with the domain of a WordPress site that has WPGraphQL installed.<\/li><li>Run <code>npm run dev<\/code> to get the app up and running locally.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Approach<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/www.apollographql.com\/docs\/react\/performance\/server-side-rendering\/\">Server-side Rendering<\/a> (SSR) through the Apollo client follows this approach:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Use Apollo Client&#8217;s <code>getDataFromTree()<\/code> function to get the results for all queries throughout your entire component tree for the current page.<\/li><li>Extract Apollo Client&#8217;s cache and send that data to the client as a global <code>window.APOLLO_STATE<\/code> object.<\/li><li>When Apollo Client initializes on the client, call its <code>new InMemoryCache().restore()<\/code> function, passing in the <code>window.APOLLO_STATE<\/code> object to seed it with the cache data from the server.<\/li><\/ol>\n\n\n\n<p>Although using the SSR approach works well with Next.js, the recommended way to do Apollo Client cache rehydration differs from that. We will instead do this:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Use Next&#8217;s <code>getStaticProps()<\/code> or <code>getServerSideProps()<\/code> function to do our data fetching and populate Apollo Client&#8217;s cache.<\/li><li>Extract Apollo Client&#8217;s cache and add it as a <code>pageProps<\/code> prop for the current page.<\/li><li>When Apollo Client initializes on the client, call its <code>new InMemoryCache().restore()<\/code> function, passing in the cache data from the server.<\/li><\/ol>\n\n\n\n<p>For more information on how the Apollo client works, check out\u00a0<a target=\"_blank\" href=\"https:\/\/github.com\/vercel\/next.js\/tree\/canary\/examples\/with-apollo\" rel=\"noreferrer noopener\">this official Next.js example project<\/a>. We&#8217;ll use that same approach for our purposes, except the code examples will be written in TypeScript rather than JS, and all the data fetching examples will be specific to WordPress and WPGraphQL.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install &amp; Configure Apollo Client<\/h2>\n\n\n\n<p>Per Apollo Client&#8217;s <a href=\"https:\/\/www.apollographql.com\/docs\/react\/get-started\/\">getting started documentation<\/a>, the <code>@apollo\/client<\/code> and <code>graphql<\/code> NPM are already installed. The <code>deepmerge<\/code> and <code>lodash<\/code> packages have also been installed, which our project leverages.<\/p>\n\n\n\n<p>To start configuring the client, open the <code>lib\/apolloClient.ts<\/code> file in a code editor. It looks like this:<\/p>\n\n\n<pre class=\"wp-block-code language-ts\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { useMemo } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { ApolloClient, HttpLink, InMemoryCache, NormalizedCacheObject } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@apollo\/client'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { relayStylePagination } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@apollo\/client\/utilities\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> merge <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'deepmerge'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> isEqual <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lodash\/isEqual'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> APOLLO_STATE_PROP_NAME = <span class=\"hljs-string\">'__APOLLO_STATE__'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">let<\/span> apolloClient: ApolloClient&lt;NormalizedCacheObject&gt; | <span class=\"hljs-literal\">undefined<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">createApolloClient<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> ApolloClient({\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">ssrMode<\/span>: <span class=\"hljs-keyword\">typeof<\/span> <span class=\"hljs-built_in\">window<\/span> === <span class=\"hljs-string\">'undefined'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">link<\/span>: <span class=\"hljs-keyword\">new<\/span> HttpLink({\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">uri<\/span>: process.env.NEXT_PUBLIC_WORDPRESS_API_URL, <span class=\"hljs-comment\">\/\/ Server URL (must be absolute)<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">credentials<\/span>: <span class=\"hljs-string\">'same-origin'<\/span>, <span class=\"hljs-comment\">\/\/ Additional fetch() options like `credentials` or `headers`<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    }),\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">cache<\/span>: <span class=\"hljs-keyword\">new<\/span> InMemoryCache({\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-comment\">\/\/ typePolicies is not required to use Apollo with Next.js - only for doing pagination.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">typePolicies<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-attr\">Query<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>          <span class=\"hljs-attr\">fields<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-attr\">posts<\/span>: relayStylePagination(),\n<\/span><\/span><span class='shcb-loc'><span>          },\n<\/span><\/span><span class='shcb-loc'><span>        },\n<\/span><\/span><span class='shcb-loc'><span>      },\n<\/span><\/span><span class='shcb-loc'><span>    }),\n<\/span><\/span><span class='shcb-loc'><span>  })\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">initializeApollo<\/span>(<span class=\"hljs-params\">initialState: NormalizedCacheObject | null = null<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> _apolloClient = apolloClient ?? createApolloClient();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ If your page has Next.js data fetching methods that use Apollo Client, the initial state<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ gets hydrated here<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (initialState) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\">\/\/ Get existing cache, loaded during client side data fetching<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> existingCache = _apolloClient.extract();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\">\/\/ Merge the existing cache into data passed from getStaticProps\/getServerSideProps<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> data = merge(initialState, existingCache, {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-comment\">\/\/ combine arrays using object equality (like in sets)<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">arrayMerge<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">destinationArray, sourceArray<\/span>) =&gt;<\/span> &#91;\n<\/span><\/span><span class='shcb-loc'><span>        ...sourceArray,\n<\/span><\/span><span class='shcb-loc'><span>        ...destinationArray.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">d<\/span>) =&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>          sourceArray.every(<span class=\"hljs-function\">(<span class=\"hljs-params\">s<\/span>) =&gt;<\/span> !isEqual(d, s))\n<\/span><\/span><span class='shcb-loc'><span>        ),\n<\/span><\/span><span class='shcb-loc'><span>      ],\n<\/span><\/span><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\">\/\/ Restore the cache with the merged data<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    _apolloClient.cache.restore(data);\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ For SSG and SSR always create a new Apollo Client<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">typeof<\/span> <span class=\"hljs-built_in\">window<\/span> === <span class=\"hljs-string\">'undefined'<\/span>) <span class=\"hljs-keyword\">return<\/span> _apolloClient;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ Create the Apollo Client once in the client<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (!apolloClient) apolloClient = _apolloClient;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> _apolloClient;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">addApolloState<\/span>(<span class=\"hljs-params\">client: ApolloClient&lt;NormalizedCacheObject&gt;, pageProps: any<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (pageProps?.props) {\n<\/span><\/span><span class='shcb-loc'><span>    pageProps.props&#91;APOLLO_STATE_PROP_NAME] = client.cache.extract();\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> pageProps;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">useApollo<\/span>(<span class=\"hljs-params\">pageProps: any<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> state = pageProps&#91;APOLLO_STATE_PROP_NAME];\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> store = useMemo(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> initializeApollo(state), &#91;state]);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> store;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s walk through each of those function definitions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">createApolloClient()<\/h3>\n\n\n\n<p>This function is responsible for creating a new instance of Apollo Client.<\/p>\n\n\n\n<p>We set Apollo Client&#8217;s <code>ssrMode<\/code> option to <code>true<\/code> if the code is running on the server, and to <code>false<\/code> if it&#8217;s running on the client.<\/p>\n\n\n\n<p>The <code>uri: process.env.NEXT_PUBLIC_WORDPRESS_API_URL<\/code> line tells Apollo Client to use the GraphQL endpoint defined in your <code>.env.local<\/code> file for all network requests.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">initializeApollo()<\/h3>\n\n\n\n<p>As its name suggests, this function initializes Apollo Client. It merges the initial state (data passed in from <code>getStaticProps()<\/code> \/ <code>getServerSideProps()<\/code>) with the existing client-side Apollo cache, then sets that new, merged data set as the new cache for Apollo Client.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">addApolloState()<\/h3>\n\n\n\n<p>This function takes the <code>pageProps<\/code> returned from <code>getStaticProps()<\/code> \/ <code>getServerSideProps()<\/code> for the current page and adds to them Apollo&#8217;s cache data. From there, Next.js takes care of passing Apollo&#8217;s cache data, along with any other page-specific props into the page component.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">useApollo()<\/h3>\n\n\n\n<p>This function calls <code>initializeApollo()<\/code> to get an instance of Apollo Client that has Apollo&#8217;s cache data added to it. This client is ultimately passed in as a prop to the <code>ApolloProvider<\/code> that Apollo Client provides.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Render an ApolloProvider<\/h2>\n\n\n\n<p>Inside of <code>_app.tsx<\/code>, we call <code>useApollo()<\/code> to get a new instance of Apollo Client, passing to it the <code>pageProps<\/code> for the current page. The  <code>apolloClient<\/code> instance is then passed in as a prop to the <code>ApolloProvider<\/code> component, which wraps our application.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { AppContext, AppInitialProps } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/app\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { ApolloProvider } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@apollo\/client\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { useApollo } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/apolloClient\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"..\/styles\/globals.css\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MyApp<\/span>(<span class=\"hljs-params\">{ Component, pageProps }: AppContext &amp; AppInitialProps<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> apolloClient = useApollo(pageProps)\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ApolloProvider<\/span> <span class=\"hljs-attr\">client<\/span>=<span class=\"hljs-string\">{apolloClient}<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ApolloProvider<\/span>&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> MyApp;<\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">How to Use in Page Components<\/h2>\n\n\n\n<p>Let&#8217;s see how we can use this Apollo Client cache rehydration superpower in our Next.js page components.<\/p>\n\n\n\n<p>Open up <code>pages\/ssg.tsx<\/code>. A simplified version of that file looks like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { gql, useQuery } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@apollo\/client\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { initializeApollo, addApolloState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/apolloClient\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> POSTS_PER_PAGE = <span class=\"hljs-number\">10<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> GET_POSTS = gql<span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  query getPosts($first: Int!, $after: String) {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    posts(first: $first, after: $after) {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      # etc.<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SSG<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> { loading, error, data } = useQuery(GET_POSTS, {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">variables<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">first<\/span>: POSTS_PER_PAGE,\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">after<\/span>: <span class=\"hljs-literal\">null<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ etc.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getStaticProps<\/span>(<span class=\"hljs-params\">context: GetStaticPropsContext<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> apolloClient = initializeApollo();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">await<\/span> apolloClient.query({\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">query<\/span>: GET_POSTS,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">variables<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">first<\/span>: POSTS_PER_PAGE,\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">after<\/span>: <span class=\"hljs-literal\">null<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> addApolloState(apolloClient, {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">props<\/span>: {},\n<\/span><\/span><span class='shcb-loc'><span>  });\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Inside of Next.js&#8217; <code>getStaticProps()<\/code> function, we call <code>initializeApollo()<\/code> to get an instance of Apollo Client that we can use for making GraphQL requests.<\/p>\n\n\n\n<p>We then call the <code>apolloClient.query()<\/code> method, passing in the exact same query and variables that are used inside of our <code>SSG<\/code> page component when it calls the <code>useQuery()<\/code> hook. You&#8217;ll notice that we&#8217;re not even using the return value that <code>apolloClient.query()<\/code> provides. This is because we don&#8217;t need it \u2013 we&#8217;re only calling <code>apolloClient.query()<\/code> to populate Apollo Client&#8217;s cache with the data for the queries executed.<\/p>\n\n\n\n<p>When our <code>SSG<\/code> page component is rendered in the browser and the <code>useQuery()<\/code> hook is called, Apollo Client will &#8220;see&#8221; that the data for the query being executed already exists it its cache, and will use that data instead of making a network request. This will result in the content on the page rendering immediately.  Visit <a href=\"http:\/\/localhost:3000\/ssg\">http:\/\/localhost:3000\/ssg<\/a> in your browser, open up the Network tab in the DevTools and refresh the page to confirm that no client-side GraphQL requests execute.<\/p>\n\n\n\n<p>More info on Next.js&#8217; <code>getStaticProps()<\/code> function can be found here: <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getstaticprops-static-generation\">https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getstaticprops-static-generation<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SSR Page<\/h3>\n\n\n\n<p>Open up <code>pages\/ssr.tsx<\/code> and visit<a href=\"http:\/\/localhost:3000\/ssg\"> http:\/\/localhost:3000\/ssr<\/a>. You can see that this file functions exactly the same as <code>ssg.tsx<\/code>, except that Next.js passes in the page props on every request since we&#8217;re using <code>getServerSideProps()<\/code> instead of <code>getStaticProps()<\/code>. Again, you can open up the Network tab in the DevTools and refresh the page to confirm that no client-side GraphQL requests execute.<\/p>\n\n\n\n<p>More info on Next.js&#8217; <code>getServerSideProps()<\/code> function can be found here: <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getserversideprops-server-side-rendering\">https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getserversideprops-server-side-rendering<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CSR Page<\/h3>\n\n\n\n<p>To prove that we still have the option to do data fetching on the client, if desired, open up <code>pages\/csr.tsx<\/code> and visit <a href=\"http:\/\/localhost:3000\/csr\">http:\/\/localhost:3000\/csr<\/a>. You can see that this page does not fetch any data on the server, since we&#8217;re not using <code>getStaticProps()<\/code> or <code>getServerSideProps()<\/code>. If you open up the Network tab in the DevTools and refresh the page, you can confirm that the GraphQL network requests execute client-side when the page first loads. You can do this if you want your request to run in the browser only, and not on the server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mixed SSG + CSR Page<\/h3>\n\n\n\n<p>Finally, open up <code>pages\/blog.tsx<\/code>. Make sure you have eleven or more posts created in your WordPress backend, then visit <a href=\"http:\/\/localhost:3000\/blog\">http:\/\/localhost:3000\/blog<\/a>.You can see that inside of <code>getStaticProps()<\/code>, an Apollo Client query is executed to get the initial list of ten blog posts, which immediately get rendered to the page when it loads. If more posts exist in the WordPress backend, the user is presented with a <code>Load more<\/code> button. Clicking this button results in Apollo Client&#8217;s <code>fetchMore()<\/code> function being called, which fires off a network request to get the next five posts and appends them to the list. Once all posts have been loaded, the user sees an <code>\u2705 All posts loaded<\/code> message.<\/p>\n\n\n\n<p>The <code>blog.tsx <\/code>page shows how you can fetch some data on the server to populate Apollo&#8217;s cache. Also, the markup appears instantly when the page loads on the front-end. After, the page fires subsequent client-side requests to fetch additional data, adding it to Apollo&#8217;s cache..<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use this Code in Your Projects<\/h2>\n\n\n\n<p>In order to use Apollo Client for SSG\/SSR\/ISR in a Next.js project, you&#8217;ll need to follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Copy <code>lib\/apolloClient.ts<\/code> into your project.<br>As stated above, set the <code>process.env.NEXT_PUBLIC_WORDPRESS_API_URL<\/code> variable to reference the GraphQL endpoint of your headless WordPress backend.<br>The object containing <code>typePolicies<\/code> that is being passed into <code>new InMemoryCache()<\/code> in this file can be omitted if you&#8217;re not doing any pagination in your project (such as the <code>fetchMore()<\/code> pagination demonstrated on the <code>pages\/blog.tsx<\/code> page).<\/li><li>In <code>pages\/_app.tsx<\/code>, call <code>useApollo(pageProps)<\/code> to get an instance of Apollo Client, then pass that in as a prop to the <code>&lt;ApolloProvider \/&gt;<\/code> component, as shown above.<\/li><li>Mimic the page components in the \/pages directory of this project, depending on whether you want your pages to do their data fetching at build time (see <code>ssg.tsx<\/code>), at request time on the server (see <code>ssr.tsx<\/code>), on the client only (see <code>csr.tsx<\/code>), or a mixture of those (see <code>blog.tsx<\/code>).<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>I hope this walk-through helps you with leveraging Apollo Client for SSG\/SSR\/ISR data fetching on your next Next.js project.<\/p>\n\n\n\n<p>And that&#8217;s it! Thanks so much for giving this post a read, and please reach out to us with any questions you have! ????<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apollo Client&nbsp;is a popular GraphQL client that can cache the results of your queries, among many other features. If you have an entirely client-side rendered (CSR) front-end app and want [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_EventAllDay":false,"_EventTimezone":"","_EventStartDate":"","_EventEndDate":"","_EventStartDateUTC":"","_EventEndDateUTC":"","_EventShowMap":false,"_EventShowMapLink":false,"_EventURL":"","_EventCost":"","_EventCostDescription":"","_EventCurrencySymbol":"","_EventCurrencyCode":"","_EventCurrencyPosition":"","_EventDateTimeSeparator":"","_EventTimeRangeSeparator":"","_EventOrganizerID":[],"_EventVenueID":[],"_OrganizerEmail":"","_OrganizerPhone":"","_OrganizerWebsite":"","_VenueAddress":"","_VenueCity":"","_VenueCountry":"","_VenueProvince":"","_VenueState":"","_VenueZip":"","_VenuePhone":"","_VenueURL":"","_VenueStateProvince":"","_VenueLat":"","_VenueLng":"","_VenueShowMap":false,"_VenueShowMapLink":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-197","post","type-post","status-publish","format-standard","hentry","category-headless"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Apollo Client Cache Rehydration in Next.js - Builders<\/title>\n<meta name=\"description\" content=\".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Apollo Client Cache Rehydration in Next.js - Builders\" \/>\n<meta property=\"og:description\" content=\".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Builders\" \/>\n<meta property=\"article:published_time\" content=\"2021-05-26T21:42:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-19T14:53:49+00:00\" \/>\n<meta name=\"author\" content=\"Kellen Mace\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:site\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kellen Mace\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/\"},\"author\":{\"name\":\"Kellen Mace\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/e6e62698d757a8421cc9723ffa8b1be3\"},\"headline\":\"Apollo Client Cache Rehydration in Next.js\",\"datePublished\":\"2021-05-26T21:42:40+00:00\",\"dateModified\":\"2023-04-19T14:53:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/\"},\"wordCount\":1501,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"articleSection\":[\"Headless\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/\",\"name\":\"Apollo Client Cache Rehydration in Next.js - Builders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\"},\"datePublished\":\"2021-05-26T21:42:40+00:00\",\"dateModified\":\"2023-04-19T14:53:49+00:00\",\"description\":\".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/apollo-client-cache-rehydration-in-next-js\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Apollo Client Cache Rehydration in Next.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"name\":\"Builders\",\"description\":\"Reimagining the way we build with WordPress.\",\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\",\"name\":\"WP Engine\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"contentUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"width\":348,\"height\":68,\"caption\":\"WP Engine\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/wpebuilders\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCh1WuL54XFb9ZI6m6goFv1g\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/e6e62698d757a8421cc9723ffa8b1be3\",\"name\":\"Kellen Mace\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g\",\"caption\":\"Kellen Mace\"},\"description\":\"Kellen Mace is the Manager of the Developer Relations team at WP Engine. He likes building modern web apps with SvelteKit, TypeScript, Tailwind, and AI tools.\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/author\\\/kellen-macewpengine-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Apollo Client Cache Rehydration in Next.js - Builders","description":".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/","og_locale":"en_US","og_type":"article","og_title":"Apollo Client Cache Rehydration in Next.js - Builders","og_description":".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.","og_url":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/","og_site_name":"Builders","article_published_time":"2021-05-26T21:42:40+00:00","article_modified_time":"2023-04-19T14:53:49+00:00","author":"Kellen Mace","twitter_card":"summary_large_image","twitter_creator":"@wpebuilders","twitter_site":"@wpebuilders","twitter_misc":{"Written by":"Kellen Mace","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/#article","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/"},"author":{"name":"Kellen Mace","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/e6e62698d757a8421cc9723ffa8b1be3"},"headline":"Apollo Client Cache Rehydration in Next.js","datePublished":"2021-05-26T21:42:40+00:00","dateModified":"2023-04-19T14:53:49+00:00","mainEntityOfPage":{"@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/"},"wordCount":1501,"commentCount":0,"publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"articleSection":["Headless"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/","url":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/","name":"Apollo Client Cache Rehydration in Next.js - Builders","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/#website"},"datePublished":"2021-05-26T21:42:40+00:00","dateModified":"2023-04-19T14:53:49+00:00","description":".Learn how to set up Apollo Client cache rehydration in a Next.js app, for better data caching with GraphQL.","breadcrumb":{"@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wpengine.com\/builders\/apollo-client-cache-rehydration-in-next-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wpengine.com\/builders\/"},{"@type":"ListItem","position":2,"name":"Apollo Client Cache Rehydration in Next.js"}]},{"@type":"WebSite","@id":"https:\/\/wpengine.com\/builders\/#website","url":"https:\/\/wpengine.com\/builders\/","name":"Builders","description":"Reimagining the way we build with WordPress.","publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wpengine.com\/builders\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wpengine.com\/builders\/#organization","name":"WP Engine","url":"https:\/\/wpengine.com\/builders\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","width":348,"height":68,"caption":"WP Engine"},"image":{"@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wpebuilders","https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g"]},{"@type":"Person","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/e6e62698d757a8421cc9723ffa8b1be3","name":"Kellen Mace","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/479f2598f161363ba2e78e1b085782477580ea3d5c4609cc9bce3be4945090d5?s=96&d=mm&r=g","caption":"Kellen Mace"},"description":"Kellen Mace is the Manager of the Developer Relations team at WP Engine. He likes building modern web apps with SvelteKit, TypeScript, Tailwind, and AI tools.","url":"https:\/\/wpengine.com\/builders\/author\/kellen-macewpengine-com\/"}]}},"_links":{"self":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/comments?post=197"}],"version-history":[{"count":0,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/197\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/media?parent=197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/categories?post=197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/tags?post=197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}