sendou.ink/lib/apollo.ts
2020-10-25 22:33:52 +02:00

70 lines
2.0 KiB
TypeScript

// https://github.com/vercel/next.js/blob/canary/examples/with-typescript-graphql/lib/apollo.ts
import {
ApolloClient,
InMemoryCache,
NormalizedCacheObject,
} from "@apollo/client";
import { Context } from "nexus-plugin-prisma/typegen";
import { useMemo } from "react";
let apolloClient: ApolloClient<NormalizedCacheObject> | undefined;
function createIsomorphLink(context: Context | {} = {}) {
if (typeof window === "undefined") {
const { SchemaLink } = require("@apollo/client/link/schema");
const { schema } = require("graphql/schema");
return new SchemaLink({ schema, context });
} else {
const { HttpLink } = require("@apollo/client");
return new HttpLink({
uri: "/api/graphql",
credentials: "same-origin",
});
}
}
function createApolloClient(context?: Context) {
return new ApolloClient({
ssrMode: typeof window === "undefined",
link: createIsomorphLink(context),
cache: new InMemoryCache({
typePolicies: {
User: {
fields: {
profile: {
merge: false,
},
},
},
},
}),
});
}
export function initializeApollo(
initialState: any = null,
// Pages with Next.js data fetching methods, like `getStaticProps`, can send
// a custom context which will be used by `SchemaLink` to server render pages
context?: Context
) {
const _apolloClient = apolloClient ?? createApolloClient(context);
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// get hydrated here
if (initialState) {
_apolloClient.cache.restore(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: any) {
const store = useMemo(() => initializeApollo(initialState), [initialState]);
return store;
}