I’m currently working on a side project (a simple habit tracker) that involves using cookie-based authentication and websockets. I’ve been referring to Apollo’s documentation and have tried using useSuspenseQuery, but I’m encountering an issue that I can’t quite figure out.
I’ve followed the documentation’s guidelines, but my queries always return unauthorized responses. This seems to be related to how URL changes trigger the useSuspenseQuery. Here’s an example: when a user navigates to the /home page, where they can view their habits, the initial habit fetch works, but it ends up triggering an "unauthorized" (while other requests on the same page work fine). Then, if the user decides to check for friends (/trends page), they also encounter an unauthorized.
This problem occurs because in my function and Apollo wrapper, I can’t read cookies whenever the URL changes because it’s executed on the server. Additionally, I can’t access local storage. Passing state from a parent component also doesn’t seem to resolve the issue.
Have you ever encountered a similar situation, or do you have any insights or recommendations for how to address this problem?
function makeClient() {
const httpLink = new HttpLink({
uri: 'https://localhost:5000/graphql',
})
const wsLink = new GraphQLWsLink(
createClient({
url: 'ws://localhost:5000/graphql',
connectionParams: () => {
return {
Authorization: `Bearer ${cookieCutter.get('accessToken')}`,
}
},
})
)
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
wsLink,
httpLink
)
const errorLink = just_error_link
const authLink = setContext((_, { headers }) => {
const accessToken = cookieCutter.get('accessToken')
if (accessToken) {
return {
headers: {
...headers,
authorization: `Bearer ${accessToken}`,
},
}
}
return {
headers: {
...headers,
},
}
})
// Connect the two links above with the Apollo Link Chain
const link = ApolloLink.from([errorLink, authLink, splitLink])
const client = new NextSSRApolloClient({
cache: new NextSSRInMemoryCache(),
link:
typeof window === 'undefined'
? ApolloLink.from([
new SSRMultipartLink({
stripDefer: true,
}),
authLink.concat(link),
])
: authLink.concat(link),
})
return client
}
export function ApolloWrapper({ children }) {
return (
<ApolloNextAppProvider makeClient={makeClient}>
{children}
</ApolloNextAppProvider>
)
}
'use client'
on top also doens’t work :/
I tried to find information on this issue, but all the documentation I came across only provided examples with a simple httpLink without any mention of authorization and sockets.
I hope to resolve this problem so that I can fetch data more efficiently. I can handle unauthorized errors because my errorLink can retry the operation when necessary and request a new access token when the refresh token is valid, which helps with unauthorized issues.