Gatsby: Include Apollo client-side

Created on 22 Jan 2018  路  8Comments  路  Source: gatsbyjs/gatsby

Description

I understand that Gatsby v2 will allow to have dynamic data client-side (e.g. to load user-specific data from some remote GraphQL API) which is great and I'm eagerly waiting for this. However as there's no ETA on v2 and I need to start with this now, I tried to integrate an Apollo GraphQL client myself (just querying a GraphQL API which has nothing to do with Gatsby) by rendering the component with the GraphQL query after componentDidMount has executed.

It works great in dev, but after building statically and opening the website I get this browser error:

screen shot 2018-01-22 at 16 29 15

There seems to be an error thrown at http://localhost:9000/component---src-layouts-en-js-851bbd767d539b6973bc.js:1:19724, but I have no idea how to know what it is, or why the error is not relayed properly.

Would you have any advice?

Environment

Gatsby version: 1.9.164
Node.js version: 9.4.0
Operating System: macOS High Sierra 10.13.2

File contents (if changed):

See https://github.com/gatsbyjs/gatsby/issues/3582#issue-289689031

Actual result

Browser error, GraphQL component does not render.

Expected behavior

No browser error, GraphQL component shows query result which gets queried successfully in dev mode.

Steps to reproduce

Most helpful comment

I have struggle for days on this. I will make a post on how to set Apollo because this was the most painful experience of my life. In the meantime for any struggling souls out there...

@shwanton As of the time of this post, you can now use apollo-boost

package.json:

"apollo-boost": "^0.1.12",
"isomorphic-fetch": "^2.2.1",
"react-apollo": "^2.1.9",
````


gatsby-ssr.js

import React from 'react';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { renderToString } from 'react-dom/server';
import fetch from 'isomorphic-fetch';
import Provider from './src/store/provider'; // This can be the React context API or Redux/Mobx

// gatsby-ssr is required for build regardless if you plan to support SSR
export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
const client = new ApolloClient({
fetch
});

const ConnectedBody = () => (

{bodyComponent}


);

replaceBodyHTMLString(renderToString());
};

gatsby-browser.js

import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
...

export const replaceRouterComponent = ({ history }) => {
const client = new ApolloClient({
fetch
});

const ConnectedRouterWrapper = ({ children }) => (




);

return ConnectedRouterWrapper;
};
```

Whatever fetch apollo-boost uses does not work when Gatsby is compiling. I tried using the npm node-fetch which did not work and didn't know how to set a custom fetch. I found the solution when I found this merge:

https://github.com/apollographql/apollo-client/pull/3590

which lead me to their docs:
https://www.apollographql.com/docs/link/links/http.html#fetch

isomorphic-fetch was the missing key which allows my Gatsby build to work.

All 8 comments

I'm also getting build errors when doinggatsby build with react-apollo. It works fine in dev.
It only happens when I try to add the graphql HOC from react-apollo.

I can include the Query component from react-apollo and that works, it's when I need a mutation and use the HOC that things break.

My hunch is that it's a conflict with the graphql global that gatsby uses and webpack is confused?

WebpackError: (0 , _reactApollo.graphql) is not a function

- AddButton.js:12 Object.doc.kind
  src/components/AddButton.js:12:16

So I fixed my issue and it was a package conflict.

I was including apollo-boost and that had it's own graphql HOC included.
I removed that package and just resorted to apollo-client and graphql-tag and things are working.

Here is my working package.json

  "dependencies": {
    "apollo-cache-inmemory": "^1.1.9",
    "apollo-cache-persist": "^0.1.1",
    "apollo-client": "^2.2.5",
    "apollo-fetch": "^0.7.0",
    "apollo-link": "^1.2.1",
    "apollo-link-http": "^1.5.1",
    "apollo-link-state": "^0.4.0",
    "gatsby": "^1.9.192",
    "gatsby-link": "^1.6.36",
    "gatsby-plugin-react-helmet": "^2.0.4",
    "gatsby-plugin-resolve-src": "^1.0.0",
    "glamor": "^2.20.40",
    "glamorous": "^4.11.4",
    "graphql-tag": "^2.8.0",
    "prop-types": "^15.6.0",
    "react-apollo": "^2.1.0-beta.3",
    "react-helmet": "^5.2.0",
    "react-redux": "^5.0.7"
  },

I have struggle for days on this. I will make a post on how to set Apollo because this was the most painful experience of my life. In the meantime for any struggling souls out there...

@shwanton As of the time of this post, you can now use apollo-boost

package.json:

"apollo-boost": "^0.1.12",
"isomorphic-fetch": "^2.2.1",
"react-apollo": "^2.1.9",
````


gatsby-ssr.js

import React from 'react';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { renderToString } from 'react-dom/server';
import fetch from 'isomorphic-fetch';
import Provider from './src/store/provider'; // This can be the React context API or Redux/Mobx

// gatsby-ssr is required for build regardless if you plan to support SSR
export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
const client = new ApolloClient({
fetch
});

const ConnectedBody = () => (

{bodyComponent}


);

replaceBodyHTMLString(renderToString());
};

gatsby-browser.js

import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
...

export const replaceRouterComponent = ({ history }) => {
const client = new ApolloClient({
fetch
});

const ConnectedRouterWrapper = ({ children }) => (




);

return ConnectedRouterWrapper;
};
```

Whatever fetch apollo-boost uses does not work when Gatsby is compiling. I tried using the npm node-fetch which did not work and didn't know how to set a custom fetch. I found the solution when I found this merge:

https://github.com/apollographql/apollo-client/pull/3590

which lead me to their docs:
https://www.apollographql.com/docs/link/links/http.html#fetch

isomorphic-fetch was the missing key which allows my Gatsby build to work.

@Legym Very nice, thank you. Do you have an example repository? Please add a link to this issue when your blog is ready!

i just deployed to netlify and it works.
my gatsby-browser.js looks like this:

```import ApolloClient from "apollo-boost";
import fetch from "isomorphic-fetch";
import React from "react";
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost";

const client = new ApolloClient({
fetch,
uri: "https://api.graph.cool/simple/v1/xxxxxxxxxxxcjt5"
});

export const wrapRootComponent = ({ Root }) => {
return () => (


);
};

Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help!

Coming to this late, but I found

I have struggle for days on this. I will make a post on how to set Apollo because this was the most painful experience of my life. In the meantime for any struggling souls out there...

@shwanton As of the time of this post, you can now use apollo-boost

package.json:

"apollo-boost": "^0.1.12",
"isomorphic-fetch": "^2.2.1",
"react-apollo": "^2.1.9",

gatsby-ssr.js

import React from 'react';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { renderToString } from 'react-dom/server';
import fetch from 'isomorphic-fetch';
import Provider from './src/store/provider'; // This can be the React context API or Redux/Mobx

// gatsby-ssr is required for build regardless if you plan to support SSR
export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const client = new ApolloClient({
    fetch
  });

  const ConnectedBody = () => (
    <ApolloProvider client={client}>
      <Provider>
        {bodyComponent}
      </Provider>
    </ApolloProvider>
  );

  replaceBodyHTMLString(renderToString(<ConnectedBody />));
};

gatsby-browser.js

import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
...

export const replaceRouterComponent = ({ history }) => {
  const client = new ApolloClient({
    fetch
  });

  const ConnectedRouterWrapper = ({ children }) => (
    <ApolloProvider client={client}>
        <AppProvider>
          <Router history={history}>{children}</Router>
        </AppProvider>
    </ApolloProvider>
  );

  return ConnectedRouterWrapper;
};

Whatever fetch apollo-boost uses does not work when Gatsby is compiling. I tried using the npm node-fetch which did not work and didn't know how to set a custom fetch. I found the solution when I found this merge:

apollographql/apollo-client#3590

which lead me to their docs:
https://www.apollographql.com/docs/link/links/http.html#fetch

isomorphic-fetch was the missing key which allows my Gatsby build to work.

Coming in late, but figured I'd mention a reference to a working repo of gatsby and apollo here:

https://github.com/jlengstorf/gatsby-with-apollo

hey i followed the process of adding apollo clien by referencing https://github.com/jlengstorf/gatsby-with-apollo (H/T @jlengstorf)
but still i can't see the content on view source for SSR

Was this page helpful?
0 / 5 - 0 ratings