Apolloのドキュメント通りに、graphql-wsでSubscriptionを実装していたのですが、以下のエラーが出ました。
https://www.apollographql.com/docs/react/api/link/apollo-link-subscriptions
Error: WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`**
コードはこんな感じです。
function MyApp({ Component, pageProps }: AppProps) {
return (
<ApolloProvider client={client}>
<Component {...pageProps} id="modalId" />
</ApolloProvider>
);
}
const httpLink = new HttpLink({
uri: 'http://~~~',
});
const wsLink = new GraphQLWsLink(
createClient({
url: 'ws://~~~',
})
);
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
httpLink
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
解決法
Next.jsのSSRが原因のようです。
function MyApp({ Component, pageProps }: AppProps) {
return (
<ApolloProvider client={client}>
<Component {...pageProps} id="modalId" />
</ApolloProvider>
);
}
const httpLink = new HttpLink({
uri: 'http://~~~',
});
const wsLink =
// ドキュメントにはないコードでwindow !== 'undefined'を追加。
typeof window !== 'undefined'
? new GraphQLWsLink(
createClient({
url: 'ws://~~~',
})
)
// ↓別の指定の方が良さそうであるが、一旦設定。
: httpLink;
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
httpLink
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});