Cannot get GraphQLWsLink to work (subscriptions) -- "Can't resolve 'fs'"?

So I have a GraphQL server that I wrote in Go, following this tutorial pretty closely. I have my front-end written as a Next.js application, and I am currently trying to create a client to connect to my server and even following the subscription docs to the T, I cannot seem to get it to work. How is it that the examples provided do not include a webSocketImpl?

If I don’t provide a webSocketImpl, I get this:

Error: WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`

So, naturally, I import { WebSocket } from "ws"; , and have:

const wsLink = new GraphQLWsLink(
	createClient({
		webSocketImpl: WebSocket,
		url: "ws://localhost:8080/subscriptions",
	})
);

Where I then get:

error - ./node_modules/node-gyp-build/index.js:1:0
Module not found: Can't resolve 'fs'

Here is the full code, basically all I need is to create a ApolloClient and export it for use in my React code.

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

const wsLink = new GraphQLWsLink(
	createClient({
		webSocketImpl: WebSocket,
		url: "ws://localhost:8080/subscriptions",
	})
);

const httpLink = new HttpLink({
	uri: `http://localhost:8080/query`,
});

const link = split(
	({ query }) => {
		const def = getMainDefinition(query);
		return (
			def.kind === "OperationDefinition" && def.operation === "subscription"
		);
	},
	wsLink,
	httpLink
);

export const Client = new ApolloClient({
	link,
	cache: new InMemoryCache(),
});

Am I totally missing something here? Is there not a default WebSocket implementation in my installation? Obviously the "ws" implementation isn’t cutting it, probably because fs is not available in-browser?

I was able to solve the problem. I was using Next.js and it seemed to be the issue was due to SSR. Basically, you just have to make sure that you are in the Browser if you want to use WebSockets (which we do for Subscriptions). My code looks like this:

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

const wsLink =
    typeof window !== "undefined"
        ? new GraphQLWsLink(
                createClient({
                    url: "ws://localhost:8080/subscriptions",
                })
          )
        : null;

const httpLink = new HttpLink({
    uri: `http://localhost:8080/query`,
});

const link =
    typeof window !== "undefined" && wsLink != null
        ? split(
                ({ query }) => {
                    const def = getMainDefinition(query);
                    return (
                        def.kind === "OperationDefinition" &&
                        def.operation === "subscription"
                    );
                },
                wsLink,
                httpLink
          )
        : httpLink;

export const client = new ApolloClient({
    link,
    cache: new InMemoryCache(),
});```
1 Like