Skip to content

Commit

Permalink
Expose apolloClient in pageContext
Browse files Browse the repository at this point in the history
For more information check vercel/next.js#8620
  • Loading branch information
guibernardino authored Oct 31, 2019
1 parent ca02ff6 commit a1403d6
Showing 1 changed file with 50 additions and 44 deletions.
94 changes: 50 additions & 44 deletions src/withData.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,54 +34,61 @@ export default apolloConfig => {
WithApollo.displayName = `withApollo(${displayName})`
}

// Allow Next.js to remove getInitialProps from the browser build
if (typeof window === 'undefined') {
if (ssr) {
WithApollo.getInitialProps = async ctx => {
const { AppTree } = ctx

let pageProps = {}
if (PageComponent.getInitialProps) {
pageProps = await PageComponent.getInitialProps(ctx)
}
if (ssr || PageComponent.getInitialProps) {
WithApollo.getInitialProps = async ctx => {
const { AppTree } = ctx

// Run all GraphQL queries in the component tree
// and extract the resulting data
const apolloClient = initApolloClient(apolloConfig, null)

try {
// Run all GraphQL queries
await require('@apollo/react-ssr').getDataFromTree(
<AppTree
pageProps={{
...pageProps,
apolloClient
}}
/>
)
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error)
}
// Initialize ApolloClient, add it to the ctx object so
// we can use it in `PageComponent.getInitialProp`.
const apolloClient = (ctx.apolloClient = initApolloClient(apolloConfig, null))

// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind()
// Run wrapped getInitialProps methods
let pageProps = {}
if (PageComponent.getInitialProps) {
pageProps = await PageComponent.getInitialProps(ctx)
}

// Extract query data from the Apollo store
const apolloState = apolloClient.cache.extract()
// Only on the server:
if (typeof window === 'undefined') {
// When redirecting, the response is finished.
// No point in continuing to render
if (ctx.res && ctx.res.finished) {
return pageProps
}

return {
...pageProps,
apolloState
// Only if ssr is enabled
if (ssr) {
try {
// Run all GraphQL queries
const { getDataFromTree } = await import('@apollo/react-ssr')
await getDataFromTree(
<AppTree
pageProps={{
...pageProps,
apolloClient
}}
/>
)
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error)
}

// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind()
}
}
}
} else if (PageComponent.getInitialProps) {
WithApollo.getInitialProps = async ctx => {
return await PageComponent.getInitialProps(ctx)

// Extract query data from the Apollo store
const apolloState = apolloClient.cache.extract()

return {
...pageProps,
apolloState
}
}
}

Expand Down Expand Up @@ -117,8 +124,7 @@ function createApolloClient(apolloConfig, initialState = {}) {
const createCache = apolloConfig.createCache || createDefaultCache

const config = {
connectToDevTools: process.browser,
ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
ssrMode: typeof window === 'undefined', // Disables forceFetch on the server (so queries are only run once)
cache: createCache().restore(initialState || {}),
...apolloConfig
}
Expand Down

0 comments on commit a1403d6

Please sign in to comment.