How do I set up Apollo and NextJS to use GraphQL Subscriptions?

Hi guys, trying to set up wss with apollo and nextjs. using this set up:

import {
  ApolloClient,
  createHttpLink,
  InMemoryCache,
  split,
} from "@apollo/client";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";

import { setContext } from "@apollo/client/link/context";
import { getMainDefinition } from "@apollo/client/utilities";


const httpLink = createHttpLink({
  uri: process.env.NEXT_PUBLIC_BACKEND_URL!,
  // ...(isLive && { credentials: "include" }),
});

const wssLink = new GraphQLWsLink(
  createClient({
    url: "wss://uk.ws.8base.com/",
    connectionParams: async () => {
      const token = await checkAuth0Token();
      return {
        token,
        workspaceId: process.env.NEXT_PUBLIC_8BASE_ENV,
        environmentName: "staging",
      };
    },
    webSocketImpl: require("websocket").w3cwebsocket,
  })
);

export const checkAuth0Token = async () => {
  if (typeof window !== "undefined") {
    const res = await fetch("/api/session");
    if (res.ok) {
      const ses = await res.json();
      return ses?.idToken || null;
    }
  }
};

const authLink = setContext(async (_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = await checkAuth0Token();
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
      // ...(isLive && { credentials: "include" }),
    },
  };
});

const cache = new InMemoryCache();

const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === "OperationDefinition" &&
      definition.operation === "subscription"
    );
  },
  wssLink,
  authLink.concat(httpLink)
);

const client = new ApolloClient({
  link: splitLink,
  cache,
  credentials: "include",
});

I just get an ‘WebSocket connection to ‘wss://uk.ws.8base.com/’ failed: undefined’ with no error message. Any idea what this may be about?

This topic should be answered in this thread: Subscriptions with Vue Apollo Next

Thanks for the reply -
So I went through that thread and got things working. However originally I was trying to use the graphql-ws package alongside apollo. I eventually made an issue request on the graphql-ws repo -

When a websocket connection is made with uk.ws.8base.com, it return with an

{
  payload: null,
  type: 'connection_ack',
}

Apparently, returning a null payload is actually against the graphql ws specification - and was causing the graphql-ws library to throw an error. This was the guys response: Error: Invalid message · Issue #348 · enisdenjo/graphql-ws · GitHub

As I mentioned, I managed to throw out the graphql-ws library and get it working using the libraries outlined in the thread above, but graphql-ws is the library apollo suggests for working with subscriptions, so it may be worth you guys checking out? - Subscriptions - Apollo GraphQL Docs

Managed to get things working on my side though, thanks again for the quick support

1 Like

Great to hear you pushed through and got it working! Thanks for the advice on this issue :+1::+1: