Skip to content

Instantly share code, notes, and snippets.

@LawJolla
Created April 20, 2021 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LawJolla/a4b577e45246681010f064de556d3068 to your computer and use it in GitHub Desktop.
Save LawJolla/a4b577e45246681010f064de556d3068 to your computer and use it in GitHub Desktop.
Apollo Client Example
import React, { useMemo } from "react"
import { ApolloClient, InMemoryCache, from } from "@apollo/client"
import { setContext } from "@apollo/client/link/context"
import { createUploadLink } from "apollo-upload-client"
import { onError } from "@apollo/client/link/error"
let apolloClient
const uri = ({ operationName }) => {
if (operationName.includes(`Sanity`)) {
return process.env.NEXT_PUBLIC_SANITY_GRAPHQL_ENDPOINT
}
return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT
}
function createIsomorphLink() {
// if (typeof window === "undefined") {
// const { SchemaLink } = require("@apollo/client/link/schema")
// const { schema } = require("./schema")
// return new SchemaLink({ schema })
// } else {
return createUploadLink({
uri,
credentials: "same-origin"
// fetch: customFetch
})
// }
}
const errorLinkFn = (errorContext) =>
onError(({ response, graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) => {
const formattedMessage = message.replace(/\[.*?\]/g, "").trim()
errorContext.handleErrors({
id: `${Math.random() * 10000}`,
errorType: `GraphQL`,
message: `${formattedMessage}`
})
})
}
if (networkError) {
errorContext.handleErrors({
id: `${Math.random() * 10000}`,
errorType: `Network`,
message: `${networkError}`
})
}
if (response && response.errors) {
response.errors = undefined
}
})
const authorizeLink = (auth) =>
setContext(async ({ operationName }, previousContext) => {
if (operationName.includes(`Sanity`)) {
return {
headers: previousContext.headers
}
}
const token = await auth.getAccessToken()
// console.log("token", token)
return {
headers: {
...previousContext.headers,
authorization: token ? `Bearer ${token}` : ""
}
}
})
const httpLink = createIsomorphLink()
function createApolloClient({ errorContext, auth, ...p }) {
console.log("creating apollo client")
const errorLink = errorLinkFn(errorContext)
const authLink = authorizeLink(auth)
return new ApolloClient({
ssrMode: typeof window === "undefined",
link: from([authLink, errorLink, httpLink]),
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
deal: (_, { args, toReference }) => {
return toReference({
__typename: "Deal",
id: args.id
})
}
}
}
}
})
})
}
export function initializeApollo(
initialState = null,
{ errorContext = null, auth = null } = {}
) {
const _apolloClient =
apolloClient ?? createApolloClient({ errorContext, auth })
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract()
// Restore the cache using the data passed from getStaticProps/getServerSideProps
// combined with the existing cached data
_apolloClient.cache.restore({ ...existingCache, ...initialState })
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === "undefined") return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) {
apolloClient = _apolloClient
}
return _apolloClient
}
export function useApollo(initialState, { errorContext, auth }) {
const store = useMemo(
() => initializeApollo(initialState, { errorContext, auth }),
[initialState]
)
return store
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment