apollographql / apollographql/apollo-client-integrations

Error: useTransportValue must be used within a streaming-specific ApolloProvider

Open
#411 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
556
Forks
53
PR merge metrics
No merged PRs in 30d

Description

sometimes it was thrown by `useSuspenseQuery`
![image](https://github.com/user-attachments/assets/e307f933-d5f7-4a86-905a-936f0f6cb7d0)

`ApolloWrapper` component file
```
'use client';

import { ApolloLink, HttpLink, split } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { getMainDefinition } from '@apollo/client/utilities';
import {
ApolloNextAppProvider,
InMemoryCache,
ApolloClient,
SSRMultipartLink,
} from '@apollo/experimental-nextjs-app-support';
import { createClient } from 'graphql-ws';
import React from 'react';
import { fragmentRegistry } from '@/graphql/query/fragment';
import { ORGANIZATION_ID, TOKEN } from '@/lib/authenticate/logged';

// have a function to create a client for you
function makeClient(cookie: {
token: string | null | undefined;
organizationId: string | null | undefined;
}) {
const httpLink = new HttpLink({
// this needs to be an absolute url, as relative urls cannot be used in SSR
uri: process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT,
// you can disable result caching here if you want to
// (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
fetchOptions: { cache: 'no-store' },
// you can override the default `fetchOptions` on a per query basis
// via the `context` property on the options passed as a second argument
// to an Apollo Client data fetching hook, e.g.:
// const { data } = useSuspenseQuery(MY_QUERY, { context: { fetchOptions: { cache: "force-cache" }}});
});
const wsLink = new GraphQLWsLink(
createClient({
url: process.env.NEXT_PUBLIC_GRAPHQL_WS_ENDPOINT as string,
connectionParams() {
return {
Authorization: `Bearer ${window?.localStorage.getItem(TOKEN)}`,
'Org-Id': window?.localStorage.getItem(ORGANIZATION_ID),
};
},
}),
);
const authLink = setContext((_, { headers }) => {
const token =
typeof window === 'undefined'
? cookie.token
: window.localStorage.getItem(TOKEN);
const organizationId =
typeof window === 'undefined'
? cookie.organizationId
: window.localStorage.getItem(ORGANIZATION_ID);
const customHeaders: Record = {};
if (token) {
customHeaders['Authorization'] = `Bearer ${token}`;
}
if (organizationId) {
customHeaders['Org-Id'] = organizationId;
}
return {
headers: {
...headers,
...customHeaders,
},
};
});
// The split function takes three parameters:
//
// * A function that's called for each operation to execute
// * The Link to use for an operation if the function returns a "truthy" value
// * The Link to use for an operation if the function returns a "falsy" value
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
ApolloLink.from([authLink, httpLink] as ApolloLink[]),
);
return new ApolloClient({
cache: new InMemoryCache({
fragments: fragmentRegistry,
}),
link:
typeof window === 'undefined'
? ApolloLink.from([
// in a SSR environment, if you use multipart features like
// @defer, you need to decide how to handle these.
// This strips all interfaces with a `@defer` directive from your queries.
new SSRMultipartLink({
stripDefer: true,
}),
authLink,
httpLink,
])
: splitLink,
});
}

// you need to create a component to wrap your app in
export function ApolloWrapper({
children,
token,
organizationId,
}: React.PropsWithChildren<{
token: string | null | undefined;
organizationId: string | null | undefined;
}>) {
return (
makeClient({ token, organizationId })}
>
{children}

);
}
```
versions
```
"@apollo/client": "^3.12.3",
"@apollo/experimental-nextjs-app-support": "^0.11.7",
"react": "^18",
"react-dom": "^18",
"next": "14.2.20",
```
What went wrong?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the ApolloWrapper component and its makeClient function, then reproduce the error from useSuspenseQuery using the listed Apollo Client, Next.js, and React versions. Inspect how ApolloNextAppProvider supplies the client and streaming context; done means identifying why the provider setup triggers the error and documenting the required correction.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, next.js, react, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.