Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
154
rated 0 times [  159] [ 5]  / answers: 1 / hits: 9693  / 4 Years ago, thu, july 23, 2020, 12:00:00

I am trying to fetch protected resource from my graphql server using nextJs and apollo client. I stored the authorization token in the client browser (localstorage) and try to read the token from apolloClient.Js file; but it throws a ReferenceError (ReferenceError: localStorage is not defined). This makes me to understand quickly that the server side was trying to reference localStorage from the backend; but fails because it is only available in the client. My question is, what is the best way to solve this issue? I am just using apollo client for the first time in my project. I have spent more than 10 hours trying to figure out the solution to this problem. I have tried so many things on web; not lucky to get the solution. Here is the code am using in apolloClient file:


import { useMemo } from 'react'
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client'
import { concatPagination } from '@apollo/client/utilities'
import { GQL_URL } from '../utils/api'

let apolloClient

const authToken = localStorage.getItem('authToken') || '';

function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: new HttpLink({
uri: GQL_URL, // Server URL (must be absolute)
credentials: 'include', // Additional fetch() options like `credentials` or `headers`
headers: {
Authorization: `JWT ${authToken}`
}

}),


cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
allPosts: concatPagination(),
},
},
},
}),
})
}

export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient()

// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
_apolloClient.cache.restore(initialState)
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient

return _apolloClient
}

export function useApollo(initialState) {
const store = useMemo(() => initializeApollo(initialState), [initialState])
return store
}

More From » reactjs

 Answers
3

I was able to solve the problem by accessing the local storage only when the window object is not 'undefined'; since it will be 'undefined' in the server side. This will work well because we don't want the server to access local storage.


import { useMemo } from 'react'
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { GQL_URL } from '../utils/api'

let apolloClient

function createApolloClient() {
// Declare variable to store authToken
let token;

const httpLink = createHttpLink({
uri: GQL_URL,
credentials: 'include',
});

const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
if (typeof window !== 'undefined') {
token = localStorage.getItem('authToken');
}
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
Authorization: token ? `JWT ${token}` : "",
}
}
});

const client = new ApolloClient({
ssrMode: typeof window === 'undefined',
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});

return client;
}

[#3101] Sunday, July 19, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jaelyn

Total Points: 619
Total Questions: 102
Total Answers: 104

Location: Honduras
Member since Sun, Dec 26, 2021
2 Years ago
jaelyn questions
;