I configured a multiclient vue apollo, but for some reason it sends requests only to localhost. However I never specified a localhost endpoint. Here is my config file
vue-apollo.js:
import Vue from "vue";
import VueApollo from "vue-apollo";
import {
createApolloClient,
restartWebsockets
} from "vue-cli-plugin-apollo/graphql-client";
Vue.use(VueApollo);
const AUTH_TOKEN = "apollo-token";
const httpsEndpoint =
process.env.VUE_APP_GRAPHQL_HTTPS || "https://myst.endpoint.prod/graphql";
export const filesRoot =
process.env.VUE_APP_FILES_ROOT ||
httpsEndpoint.substr(0, httpsEndpoint.indexOf("/graphql"));
Vue.prototype.$filesRoot = filesRoot;
const defaultOptions = {
httpsEndpoint,
wssEndpoint:
process.env.VUE_APP_GRAPHQL_WSS || "wss://myst.endpoint.prod/graphql",
tokenName: AUTH_TOKEN,
persisting: false,
websocketsOnly: false,
ssr: false
};
const clientAOptions = {
httpsEndpoint: "https://myst.endpoint.prod/graphql"
};
const clientBOptions = {
httpsEndpoint: "https://mynd.endpoint.prod/graphql"
};
export function createProvider(options = {}) {
const createA = createApolloClient({
...defaultOptions,
...clientAOptions
});
const createB = createApolloClient({
...defaultOptions,
...clientBOptions
});
const a = createA.apolloClient;
const b = createB.apolloClient;
const apolloProvider = new VueApollo({
clients: {
a,
b
},
defaultClient: a,
defaultOptions: {
$query: {
}
},
errorHandler(error) {
console.log(
"%cError",
"background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;",
error.message
);
}
});
return apolloProvider;
}
export async function onLogin(apolloClient, token) {
if (typeof localStorage !== "undefined" && token) {
localStorage.setItem(AUTH_TOKEN, token);
}
if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient);
try {
await apolloClient.resetStore();
} catch (e) {
console.log("%cError on cache reset (login)", "color: orange;", e.message);
}
}
export async function onLogout(apolloClient) {
if (typeof localStorage !== "undefined") {
localStorage.removeItem(AUTH_TOKEN);
}
if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient);
try {
await apolloClient.resetStore();
} catch (e) {
console.log("%cError on cache reset (logout)", "color: orange;", e.message);
}
}
I edidted this file according to documentation. Why does apollo send request to wrong endpoint and how to fix it? I edidted this file according to documentation. Why does apollo send request to wrong endpoint and how to fix it? I
Related
I am working on an application where I am trying to implement common functions which will call an API endpoint here is my implementation using vue3.
Page
<script>
import httpService from "./services/HttpService.vue";
export default {
data() {
return {
weather: undefined,
error : false,
errormessage : "",
};
},
methods : {
async fetchWeather(e) {
if (e.key == "Enter" && this.query) {
let {response} =await get(query,`${weather_url}forecast?city=`); //await axios.get(`${this.url_base}forecast?city=${this.query}`);
this.setResults(response.data);
}else if (e.key == "Enter" && !this.query){
this.error = true;
this.errormessage = 'Please enter name to search!';
}
},
setResults(res) {
if(res.isSuccessful === true){
this.error = false;
this.weather = res.response;
}else{
this.weather = undefined;
this.errormessage = res.response;
this.error = true;
}
}
},
};
</script>
Service
<script>
import axios from "axios";
export default async function GenericService() {
async function get(query,url) {
try {
let response = await axios.get(`${base_url}${url}${this.query}`);
return response;
} catch (err) {
throw new Error(err);
}
}
}
</script>
GlobalUrl
<script>
export const ConstantBaseUrl = {
base_url: "https://localhost:7005/",
};
export const EndPointUrl = {
weather_url : "api/weather/"
}
</script>
Here I want to achieve is there must be a common method that will be used to send a get request to my backend API. My code is not working and I know I am I might be missing something or doing it the wrong way because I am totally new to Vue3.js.
I have been messing around with Vue and trying to learn it. On the first click of the button in LoginForm.vue token and user_data are both null. On the second click it finally gets updated. How can I get the live reactive state of the variables?
I am new to Vue so if there are better common practices please let me know.
store/login.js
import { defineStore } from 'pinia'
import axios from 'axios'
export const useUsers = defineStore('users', {
state: () => ({
token: null,
user_data: null
}),
actions: {
async loginUser(data) {
try {
let response = await axios.post("users/login", data)
// Object.assign(this.token, response.data.token)
this.token = response.data.token
axios.defaults.headers.common['user-token'] = this.token
} catch (error) {
return error
}
},
async logout() {
// Object.assign(this.token, null)
// Object.assign(this.user_data, null)
this.token = null
this.user_data = null
// localStorage.removeItem('user');
delete axios.defaults.headers.common['user-token']
},
async login_and_get_user_data(data) {
axios.post("users/login", data).then(response => {
this.token = response.data.token
axios.defaults.headers.common['user-token'] = this.token
axios.get("users/user").then(response2 => {
this.user_data = response2.data.user
})
})
},
async get_user_data() {
console.log(JSON.parse(localStorage.getItem('user'))['token'])
axios.defaults.headers.common['user-token'] = JSON.parse(localStorage.getItem('user'))['token']
let response = await axios.get("users/user")
// Object.assign(this.user_data, response.data.user)
this.user_data = response.data.user
}
}
})
components/LoginForm.vue
<script>
import { useUsers } from '#/stores/login'
import { mapActions } from 'pinia'
import { storeToRefs } from 'pinia'
import { isProxy, toRaw } from 'vue';
export default {
setup() {
const store = useUsers()
store.$subscribe((mutation, state) => {
localStorage.setItem('user', JSON.stringify(state))
})
},
data() {
return {
email: "",
password: ""
}
},
methods: {
...mapActions(useUsers, ['loginUser']),
...mapActions(useUsers, ['get_user_data']),
...mapActions(useUsers, ['logout']),
on_click() {
var data = new FormData();
data.append('email', this.email);
data.append('password', this.password);
const store = useUsers()
this.loginUser(data)
this.get_user_data()
const { token } = storeToRefs(store)
const { user_data } = storeToRefs(store)
console.log(token.value)
console.log(toRaw(user_data.value))
},
logout_click() {
this.logout().then(
console.log(JSON.parse(localStorage.getItem('user')))
)
}
}
}
</script>
<template>
<input type="email" v-model="email" placeholder="youremail#mail.com">
<br>
<input type="password" v-model="password">
<br>
<button #click="on_click">Submit</button>
<br>
<button #click="logout_click">Logout</button>
</template>
Your method on_click is calling async methods like loginUser or get_user_data without waiting them to be finished.
So by the time your are logging console.log(token.value) your http request is probably not finished yet and your token is still null.
You need to await the methods that are doing those requests.
async on_click() {
var data = new FormData();
data.append('email', this.email);
data.append('password', this.password);
const store = useUsers()
await this.loginUser(data)
await this.get_user_data()
const { token } = storeToRefs(store)
const { user_data } = storeToRefs(store)
console.log(token.value)
console.log(toRaw(user_data.value))
},
Keep in mind that you will probably need to display a loader to give the user a feedback because the on_click is now asynchronous and take a bit more time
In my extjs application , authorization works on the local host , but the page server gives an error : Application error: a client-side exception has occurred (see the browser console for more information) . They want a login, password are saved to the database, when logging in, a redirect to a page protected via axios is successfully performed, and there is an error there.
The cook's locale is saved correctly, but apparently cannot be counted from there.
I added a header (Access-Control-Allow-Origin) to the request, it didn't help.
My service :
import axios, {AxiosError} from "axios";
import { Router, useRouter } from "next/router";
import { useQuery } from "react-query";
const host = process.env.HOST || 'http://localhost:3000'
// axios instance
export const apiClient = axios.create({
baseURL: host + "/api",
withCredentials: true,
headers: {
"Content-type": "application/json"
},
});
export type Admin = {
id: string
login: string
}
export type RedirectError = {
redirectUrl: string
}
export const getSession = async () => {
const response = await apiClient.get<Admin>('getSession')
return response.data
}
export const useSession = () => {
const router = useRouter()
const { isLoading, error, data, isSuccess } = useQuery<Admin, AxiosError<RedirectError>>('sid', getSession)
if (error) router.push(error.response.data.redirectUrl)
return { isLoading, error, data, isSuccess }
}
My api/getSession:
import type { NextApiRequest, NextApiResponse } from 'next'
import checkSession from '../../src/services/checkCookie'
export default async function getSession(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
try {
const sid = req.cookies['sid']
const admin = await checkSession(sid)
if (admin) {
const { id, login } = admin.admin
return res.send({ id, login })
}
const host = process.env.NODE_ENV === 'production' ? process.env.HOST : 'http://localhost:3000'
return res.status(401).send({ redirectUrl: host + '/admin/login' })
} catch (error) {
console.error(error)
res.status(500).send({ message: "" })
}
} else {
res.status(404).send({ message: "" })
}
}
checkSession in getSession api :
export default async function checkSession (token: string) {
// const token = req.cookies['sid']
if (typeof window === 'undefined' && token) {
const unsign = (await import('./signature')).unsign
const sessionToken = unsign(token, process.env.SECRET!)
if (sessionToken && typeof sessionToken === 'string') {
const db = (await import('../../prisma')).default
const session = await db.session.findUnique({ where: { sessionToken },
include: { admin: true } })
if (session) {
return { admin: session.admin }
}
}
}
}
Page with axios
import { NextPage } from "next"
import TableService from "../src/component/TableService"
import AdminLayout from "../src/component/admin/AdminLayout"
import { Admin, getSession, RedirectError, useSession } from "../src/services/apiClient"
import { useRouter } from "next/router"
import { CircularProgress } from "#mui/material"
const AdminTable: NextPage = () => {
const router = useRouter()
const {isLoading, error, data, isSuccess } = useSession()
if (isLoading) return <CircularProgress />
return (
<>
{data && <div>{data.login}</div>}
{isSuccess &&
<AdminLayout title="">
<TableService />
</AdminLayout>
}
{isLoading && <p>Loading..</p>}
{error && <p>Error occurred!</p>}
</>
)
}
export default AdminTable
I'm doing a little api with register and auth using jwt, apollo-vue and graphql
I can`t get data through queries (or set it through mutations) from/to my backend.
But i can do it from Postman, cause i know how to send a token in the headers.
I'm too try to call onLogin(apolloClient, token) bellow the action login from vuex. Nothings work
I'm very newby with backend, i will appreciate any advice
Another problem? : If in the function below...
const authLink = setContext(async (_, { headers }) => {
// add here console.log(localStorage.getItem('apollo-token'))
const token = await localStorage.getItem('apollo-token')
// and then console.log(token)
return {...}
})
The first console print a token, but the second console print null. This is weird for me.
This is my vue-apollo.js
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { createApolloClient, restartWebsockets } from 'vue-cli-plugin-apollo/graphql-client'
import { setContext } from 'apollo-link-context'
Vue.use(VueApollo)
const AUTH_TOKEN = 'apollo-token'
// Http endpoint
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:3000/graphql'
const authLink = setContext(async (_, { headers }) => {
const token = await localStorage.getItem(AUTH_TOKEN)
return {
...headers,
Authorization: token || ''
}
})
// Files URL root
export const filesRoot = process.env.VUE_APP_FILES_ROOT || httpEndpoint.substr(0, httpEndpoint.indexOf('/graphql'))
Vue.prototype.$filesRoot = filesRoot
// Config
const defaultOptions = {
httpEndpoint,
wsEndpoint: null,
tokenName: AUTH_TOKEN,
websocketsOnly: false,
ssr: false,
link: authLink
}
export const { apolloClient } = createApolloClient({
...defaultOptions,
})
export function createProvider(options = {}) {
const { apolloClient, wsClient } = createApolloClient({
...defaultOptions,
...options,
})
apolloClient.wsClient = wsClient
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$query: {
// fetchPolicy: 'cache-and-network',
},
},
errorHandler(error) {
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
},
})
return { apolloProvider, apolloClient }
}
// Manually call this when user log in
export async function onLogin(apolloClient, token) {
if (typeof localStorage !== 'undefined' && token) {
localStorage.setItem(AUTH_TOKEN, token)
}
if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)
try {
await apolloClient.resetStore()
} catch (e) {
// eslint-disable-next-line no-console
console.log('%cError on cache reset (login)', 'color: orange;', e.message)
}
}
// Manually call this when user log out
export async function onLogout(apolloClient) {
if (typeof localStorage !== 'undefined') {
localStorage.removeItem(AUTH_TOKEN)
}
if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)
try {
await apolloClient.resetStore()
} catch (e) {
// eslint-disable-next-line no-console
console.log('%cError on cache reset (logout)', 'color: orange;', e.message)
}
}
main.js from vue
// HTTP connection to the API
const httpLink = createHttpLink({
// You should use an absolute URL here
uri: 'http://localhost:3000/graphql',
})
// Cache implementation
const cache = new InMemoryCache()
// Create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache,
})
Vue.config.productionTip = false
Vue.use(VueScreen)
.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
new Vue({
router,
store,
vuetify,
apolloProvider,
render: h => h(App)
}).$mount('#app')
EDIT: more code
This is the query, in a view on vue
import gql from "graphql-tag";
export default {
name: "Home",
apollo: {
Users: gql`
{
Users {
_id
username
email
password
token
createdAt
}
},
`,
},
};
The error that i receive is:
bundle.esm.js:75 POST http://localhost:3000/graphql 500 (Internal Server Error)
Error sending the query 'Users' ServerError: Response not successful: Received status code 500
at throwServerError
In the backend, this is my query
Query: {
async Users(_, req, context) {
const auth = checkAuth(context)
if (auth.id) {
const users = await User.find()
users.forEach(e => {
e.password = null
})
return users
} else {
return new Error("must be logged.")
}
},
and this is my checkAuth.js
import jwt from 'jsonwebtoken'
import { AuthenticationError } from 'apollo-server'
import 'dotenv/config'
module.exports = (context) => {
const authHeader = context.headers.authorization;
console.log("headers: ",context.headers)
if (authHeader) {
const token = authHeader.split('Bearer ')[1];
if (token) {
try {
const user = jwt.verify(token, process.env.SECRET_KEY);
return user
} catch (err) {
return new AuthenticationError("Invalid token.")
}
}
return new Error("Token must be 'Bearer [token]'")
}
return new Error("I need a token bro!")
}
EDIT 2
the context.header received on the backend
headers: {
host: 'localhost:3000',
connection: 'keep-alive',
'content-length': '160',
'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
accept: '*/*',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
'content-type': 'application/json',
origin: 'http://localhost:8081',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'http://localhost:8081/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'es-419,es;q=0.9,en;q=0.8'
},
The vue-apollo.js file is not used.
In your main.js the apolloClient you inject in Vue is declared in the main.js and doesn't contain the authLink. All your code in vue-apollo.js isn't called.
So instead of this:
// HTTP connection to the API
const httpLink = createHttpLink({
// You should use an absolute URL here
uri: 'http://localhost:3000/graphql',
})
// Cache implementation
const cache = new InMemoryCache()
// Create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache,
})
Vue.config.productionTip = false
Vue.use(VueScreen)
.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
new Vue({
router,
store,
vuetify,
apolloProvider,
render: h => h(App)
}).$mount('#app')
Try this:
import { createProvider } from 'vue-apollo.js';
Vue.config.productionTip = false
Vue.use(VueScreen)
.use(VueApollo)
const { apolloProvider, apolloClient } = createProvider();
new Vue({
router,
store,
vuetify,
apolloProvider,
render: h => h(App)
}).$mount('#app')
From what i see, you only send the token in the authorization header.
const authLink = setContext(async (_, { headers }) => {
const token = await localStorage.getItem(AUTH_TOKEN)
return {
...headers,
Authorization: token || ''
}
})
but in the backend you expect to find a bearer token:
module.exports = (context) => {
const authHeader = context.headers.authorization;
console.log("headers: ",context.headers)
if (authHeader) {
const token = authHeader.split('Bearer ')[1]; << Your code is breaking here
if (token) {
try {
const user = jwt.verify(token, process.env.SECRET_KEY);
return user
} catch (err) {
return new AuthenticationError("Invalid token.")
}
}
return new Error("Token must be 'Bearer [token]'")
}
return new Error("I need a token bro!")
}
You must send 'Bearer [token]' instead of just the token. Like so:
const authLink = setContext(async (_, { headers }) => {
const token = await localStorage.getItem(AUTH_TOKEN)
return {
...headers,
Authorization: `Bearer ${token}`
}
})
In the documentation this is how setContext is used:
const setAuthorizationLink = setContext((request, previousContext) => ({
headers: {authorization: "1234"}
}));
The setContext function takes a function that returns either an object or a promise that returns an object to set the new context of a request.
In the code below you only return the headers. When you're supposed to return the context.
const authLink = setContext(async (_, { headers }) => {
const token = await localStorage.getItem(AUTH_TOKEN)
return {
...headers,
Authorization: token || ''
}
})
Try this instead
const authLink = setContext(async (_, { headers }) => {
const token = await localStorage.getItem(AUTH_TOKEN)
return {
headers: {
...headers,
Authorization: token || ''
}
}
})
Can anyone tell me from where I can import apolloClient so that I can make requests to apollo?
I usually get an error either mutate is not a function (even if I pass in this.$apollo from a Vue component)
I am just trying to get into the way of things in Vue. If any hints on code and structure I would appreciate that
signIn component
<template>
<div class="signIn-component">
<form #submit.prevent="signInUser()">
<input
type="email"
placeholder="Enter your email"
v-model="formInput.email"
/>
<input
type="password"
placeholder="Enter your password"
v-model="formInput.password"
/>
<button>Sign In</button>
</form>
</div>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
const { mapActions } = createNamespacedHelpers("auth");
export default {
data() {
return {
formInput: {
email: null,
password: null
}
};
},
methods: {
// Vuex Actions
...mapActions(["signIn"]),
signInUser: function() {
// eslint-disable-next-line no-unused-vars
this.signIn(this.formInput, this.$apollo).then(_ =>
this.$route.push("/")
);
}
}
};
</script>
<style></style>
Vuex.auth
import { apolloClient } from 'vue-cli-plugin-apollo/graphql-client';
import SignInGQL from "#/graphql/signIn.gql";
export default {
namespaced: true,
state: {
token: null,
user: {},
authStatus: false
},
getters: {
isAuthenticated: state => !!state.token,
authStatus: state => state.authStatus,
user: state => state.user
},
actions: {
async signIn({ commit, dispatch }, formInput) {
console.log('here');
try {
const { data } = await apollo.mutate({
mutation: SignInGQL,
variables: { ...formInput }
})
const { token } = data.signIn;
console.log(token);
commit('setToken', token);
localStorage.setItem('auth-token', token);
dispatch('setUser', token);
} catch (e) {
console.error(e)
}
},
setUser({ commit }, token) {
const encodedPayload = token.split('.')[1];
const { payload } = JSON.parse(atob(encodedPayload));
console.log('payload: ', payload);
// TODO: Set User information
commit('signInUser', payload);
}
},
mutations: {
setToken(state, token) {
state.token = token
},
signInUser(state, user) {
state.authStatus = true
state.user = { ...user }
},
// logOutUser(state) {
// state.authStatus = ''
// state.token = '' && localStorage.removeItem('auth-token')
// }
}
}
This question explains adding headers to apollo client
solution repo
import { setContext } from "apollo-link-context";
import { ApolloClient, InMemoryCache, HttpLink } from "apollo-boost";
import VueApollo from "vue-apollo";
Vue.use(VueApollo);
const httpLink = new HttpLink({
uri: "http://sebapi.com/graphql"
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from ApplicationSettings if it exists
const token = ApplicationSettings.getString("token");
// return the headers to the context so HTTP link can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : null
}
};
});
// update apollo client as below
const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient
});
and LOGIN.VUE
<script lang="ts">
export default {
data() {
return {
jwt: "",
user: {
identifier: "test",
password: "123123",
},
};
},
methods: {
handleLogin() {
request({
url: "http://sebapi.com/auth/local",
method: "POST",
headers: { "Content-Type": "application/json" },
content: JSON.stringify({
identifier: this.user.identifier,
password: this.user.password,
}),
})
.then(
(response) => {
const result = response.content.toJSON();
console.log("Result from Server: ", result);
//ignore applicationsettings it's just a kind of localstore in nativescript
ApplicationSettings.setString("token", result.jwt);
},
(e) => {
console.error(e);
//ignore nativateto its routing in nativescript
this.$navigateTo(routes.login);
}
)
.then(() => {
this.$navigateTo(routes.app);
});
},
},
};
</script>
This is how I did it, in case somebody is looking for the same answer:
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { createApolloClient } from 'vue-cli-plugin-apollo/graphql-client'
// Install the vue plugin
Vue.use(VueApollo)
// Name of the localStorage item
const AUTH_TOKEN = 'auth-token'
// Http endpoint
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:3000/graphql';
// Config
const defaultOptions = {
// You can use `https` for secure connection (recommended in production)
httpEndpoint,
// You can use `wss` for secure connection (recommended in production)
// Use `null` to disable subscriptions
wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || null,
// wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws://localhost:3000/graphql',
// LocalStorage token
tokenName: AUTH_TOKEN,
// Enable Automatic Query persisting with Apollo Engine
persisting: false,
// Use websockets for everything (no HTTP)
// You need to pass a `wsEndpoint` for this to work
websocketsOnly: false,
// Is being rendered on the server?
ssr: false,
// Override default apollo link
// note: don't override httpLink here, specify httpLink options in the
// httpLinkOptions property of defaultOptions.
// httpLinkOptions: {
// headers: {
// Authorization: authHeader
// }
// }
// Override default cache
// cache: myCache
// Override the way the Authorization header is set
// getAuth: (tokenName) => getUserToken(),
// Additional ApolloClient options
// apollo: { ... }
// Client local data (see apollo-link-state)
// clientState: { resolvers: { ... }, defaults: { ... } }
}
export const { apolloClient, wsClient } = createApolloClient({
...defaultOptions,
// ...options,
})
// Call this in the Vue app file
export function createProvider() {
// Create apollo client
apolloClient.wsClient = wsClient
// Create vue apollo provider
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$query: {
fetchPolicy: 'cache-and-network',
},
},
errorHandler(error) {
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
},
})
return apolloProvider
}
This is the source I found the solution
If you have any recommendations, feel free to leave them here, please!