Skip to content

Instantly share code, notes, and snippets.

@ziedHamdi
Created August 5, 2022 13:05
Show Gist options
  • Save ziedHamdi/78844e6c3cc919d714b234a2630ba71b to your computer and use it in GitHub Desktop.
Save ziedHamdi/78844e6c3cc919d714b234a2630ba71b to your computer and use it in GitHub Desktop.
client.js
import {useMemo} from 'react'
import {ApolloClient, gql} from '@apollo/client'
// import {HttpLink} from '@apollo/client/link/http'
import {from, HttpLink} from '@apollo/client'
import { onError } from "@apollo/client/link/error";
import merge from 'deepmerge'
import {createCache} from './cache'
import {isSSR} from "../constants/util";
import isEqual from 'lodash/isEqual'
import logger from "../lib/logger";
import AuthenticationError from "../lib/error/AuthenticationError";
import {signIn} from "next-auth/react";
export const APOLLO_STATE_PROP_NAME = '__APOLLO_STATE__'
const typeDefs = gql`
extend type Query {
draftComplaints: [Complaint]
}
`;
let _apolloClient
// Log any GraphQL errors or network error that occurred
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ errorCode, message, locations, path, ...other }) => {
if (errorCode == AuthenticationError.errors.NOT_AUTHENTICATED) {
signIn()
}
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}, other: ${JSON.stringify(other)} `
)
}
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
function createIsomorphLink() {
if (typeof window === 'undefined') {
const frontEndGraphQLUrl = process.env.NEXT_PUBLIC_FRONT_END_SSR_URL + '/api/graphql'
logger.debug("server side next links are pointing to ", frontEndGraphQLUrl)
return new HttpLink({
uri: frontEndGraphQLUrl,
headers: {ssr: true},
credentials: 'same-origin',
})
} else {
return new HttpLink({
uri: '/api/graphql',
headers: {ssr: false},
credentials: 'same-origin',
})
}
}
function createApolloClient( cache ) {
let defaultOptions = {}
if (typeof window === 'undefined') {
defaultOptions = {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
}
}
} else {
defaultOptions = {
query: {
fetchPolicy: 'cache-and-network',
errorPolicy: 'all',
}
}
}
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: from([errorLink, createIsomorphLink()]),
cache,
typeDefs,
defaultOptions
})
}
export function initializeApollo(initialState = null) {
if (isSSR()) {
return createApolloClient(createCache())
}
const apolloClient = _apolloClient ?? createApolloClient(createCache())
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// get hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = apolloClient.extract()
// Merge the existing cache into data passed from getStaticProps/getServerSideProps
const data = merge(initialState, existingCache, {
// combine arrays using object equality (like in sets)
arrayMerge: (destinationArray, sourceArray) => [
...sourceArray,
...destinationArray.filter((d) =>
sourceArray.every((s) => !isEqual(d, s))
),
],
})
// Restore the cache with the merged data
apolloClient.cache.restore(data)
}
// For SSG and SSR always create a new Apollo Client
// Create the Apollo Client once in the client
if (!_apolloClient) _apolloClient = apolloClient
return apolloClient
}
export function useApollo(pageProps) {
const state = pageProps[APOLLO_STATE_PROP_NAME]
const store = useMemo(() => initializeApollo(state), [state])
return store
}
export function addApolloState(client, pageProps) {
if (pageProps?.props) {
pageProps.props[APOLLO_STATE_PROP_NAME] = client.cache.extract()
}
return pageProps
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment