I'm trying to change the default header of my Apollo Graph QL Client INSIDE a react component and I simply cant manage to find anything in the docs. So in my index.js I create and link my client as described and add a JWT Token header. But what if I want to change the headers inside my React Component. For example, I want to replace the Token on reauthenticate.
In Axios you can simply do something with this.
axios.defaults.headers.common['Auth-Token'] = 'foo bar';
How can I do something like that with React Apollo? Here is he important part of my index.js
const httpLink = createHttpLink({
uri: 'https://somesecureapi',
});
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
I tried to export the client and then import it to the component create a new Link and changethe old one but this didn't work.
There must be some easier way for this. Any suggestions
createHttpLink
accept fetch
options, in which you can custom how you want your fetch
to behave. A simple implementation could look like this:
import { ApolloProvider, graphql } from "react-apollo";
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
const customFetch = (uri, options) => {
return fetch(uri, {
...options,
headers: {
...options.headers,
"x-custom-header": "custom value"
}
});
};
const fetchLink = createHttpLink({
uri: "https://graphql-pokemon.now.sh",
fetch: customFetch
});
const client = new ApolloClient({
link: ApolloLink.from([fetchLink]),
cache: new InMemoryCache()
});
As you can see in customFetch
, I added x-custom-header
with "custom value"
. This will be applied to all query that uses this client. But, I am also spreading options.headers
for the fetch
options, so any headers that come will be passed through.
In our component, we can pass extra headers like this:
const WrappedPokemon = graphql(PokemonQuery, {
options: {
context: { headers: { "x-another-custom-header": "another custom value" } }
},
props: ({ data }) => ({
loading: data.loading,
pokemon: data.pokemon || {}
})
})(Pokemon);
This extra header will only exist for this query only, unlike the one above.
I have made a simple implementation in codesandbox to help you understand the implementation.