So I am using the https://github.com/nuxt-community/apollo-module
I am trying to set this up to connect to my shopify graphql API
On nuxt.config.js:
apollo: {
clientConfigs: {
default: {
httpEndpoint: 'https://my-store.myshopify.com/admin/api/2020-01/graphql.json',
getAuth: () => 'Bearer 26cfd63bbba75243b55fad2c8de0a12f'
},
}
},
on index.vue, i have the following:
<script>
import gql from 'graphql-tag'
export default {
apollo: {
data: {
query: gql`
query {
shop {
name
}
}
`,
}
}
}
</script>
is this the correct set up?
I appear to be getting a cors policy error. I believe this is to do with missing headers that Shopify requires: https://help.shopify.com/en/api/graphql-admin-api/getting-started#authentication
how do I add 'X-Shopify-Access-Token' to the setup?
Any help would be much appreciated.
Thanks
This is how we have it working in our Nuxt Config.
apollo: {
clientConfigs: {
default: {
httpEndpoint:
"http://api.another-backend-example.com/graphql",
persisting: false
},
shopify: {
httpEndpoint:
"https://my-store.myshopify.com/api/2019-07/graphql.json",
httpLinkOptions: {
headers: {
"Content-Type": "application/json",
"X-Shopify-Storefront-Access-Token":
"123456789abcdefghi"
}
},
persisting: false
}
}
}
We also built a lot of useful Shopify components for Nuxt, maybe this helps you: https://github.com/funkhaus/shophaus/
Related
As the title suggest, I am trying to add a header to all queries and mutations made by apollo. I know I can do
context: {
headers: {
'Accept-Language': $this.i18n.current;
}
}
but that is only for one query or mutation. I am using nuxt with vue and my current nuxt.config.js is as follows
apollo: {
clientConfigs: {
default: '~/plugins/apollo-config.js'
},
defaultOptions: {
$query: {
fetchPolicy: 'network-only',
context: { // does not work
headers: {
"Accept-Language": $this.i18n.current, // not sure if this works as it is in config
}
}
}
},
errorHandler: '~/plugins/apollo-error-handler.js'
},
I'm pretty sure I'm using context wrong in this case but not sure how else I should do it. Any help would be very much appreciated.
I'm not at all a professional regarding GraphQL but last year, I've achieved something that works well (with a JWT header), here is what I had back at the time
nuxt.config.js
apollo: {
clientConfigs: {
default: '#/plugins/nuxt-apollo-config.js',
},
defaultOptions: {
$query: {
loadingKey: 'loading',
fetchPolicy: 'network-only',
},
},
authenticationType: 'Bearer',
},
and here is my
nuxt-apollo-config.js file
import { setContext } from 'apollo-link-context'
import { from } from 'apollo-link'
import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'
import { createHttpLink } from '#apollo/client/core'
import schema from '../apollo/schema.json'
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData: schema,
})
export default ({ app, $config: { baseUrlGraphql } }) => {
const headersConfig = setContext(() => ({
credentials: 'same-origin',
headers: {
Authorization: app.$cookies.get('auth._token.local'),
'x-company-id': app.$cookies.get('company_id'),
},
}))
const cache = new InMemoryCache({ fragmentMatcher, resultCaching: false })
return {
defaultHttpLink: false,
link: from([
headersConfig,
createHttpLink({
credentials: 'include',
uri: baseUrlGraphql,
fetch: (uri, options) => {
return fetch(uri, options)
},
}),
]),
cache,
}
}
import { setContext } from 'apollo-link-context' worked well for me. I'm not sure that it's the best because there is maybe something baked-in right now but this one worked for me last year.
I added middlewares to default.vue component:
export default {
components: {
TheHeader
},
middleware: ['auth'],
}
My auth.js:
export default function ({ app, store }) {
if (app.$cookies.get('AUTH_TOKEN')) {
var AUTH_TOKEN = app.$cookies.get('AUTH_TOKEN')
app.$axios.$post('https://example.com/api', {
email: Buffer.from(AUTH_TOKEN[0], 'base64').toString(),
password: Buffer.from(AUTH_TOKEN[1], 'base64').toString(),
}).then(response => {
store.dispatch('changeAuthStatus', {
authStatus: true,
userData: {
id: response.data.id,
login: response.data.login,
email: response.data.email,
firstName: response.data.first_name,
lastName: response.data.last_name,
}
})
})
}
}
So I can't understand why my middlewares don't load when the page is reloaded or with direct access to the page. Also mode: 'universal' and ssr: true are set in nuxt.config.js
Here is the documentation for the middlewares: https://nuxtjs.org/docs/2.x/directory-structure/middleware/
Few steps to have a working middleware:
use it only in a page (/pages/hello.vue) or layout (/layouts/MyFancyLayout.vue)
put the middleware in the proper directory (/middleware/test.js)
call it properly in the .vue file like middleware: 'test'
You can also try to debug and see if something like this works
export default {
middleware() {
console.log('working!')
}
}
It is working on client transitions and should be good on initial page load aswell.
As a more accurate way, you should do this in the Vuex Store using the 'context' attribute.
middleware/auth.js
export default function(context) {
if (process.client) {
context.store.dispatch('initAuth', null);
}
context.store.dispatch('initAuth', context.req);
}
store/index.js
import Cookie from 'js-cookie'
store/index.js
actions:{
initAuth(vuexContext,state){
let token;
let jwtCookie;
if (req) {
if (!req.headers.cookie) {
return;
}
jwtCookie = req.headers.cookie
.split(";")
.find(c => c.trim().startsWith("jwt="));
if (!jwtCookie) {
return;
}
token = jwtCookie.split('=')[1];
} else {
token = localStorage.getItem('token');
}
vuexContext.commit('setToken', token);
return $axios.post('https://example.com/api', {
email: Buffer.from(AUTH_TOKEN[0], 'base64').toString(),
password: Buffer.from(AUTH_TOKEN[1], 'base64').toString(),
}).then(response => {
vuexContext.commit('changeAuthStatus', {
authStatus: true,
userData: {
id: response.data.id,
login: response.data.login,
email: response.data.email,
firstName: response.data.first_name,
lastName: response.data.last_name,
}
})
})
}
}
this way it will work smoothly and understandably
I've been trying to get this to work for two days now. I'm a brand new user to Nuxt (although I've used Vue for a few years now), so I'm just trying to wrap my brain around how this all works.
In my Nuxt project I have the Axios module installed:
nuxt.config.js
export default {
plugins: [
...
'~/plugins/axios',
],
axios: {
baseURL: 'https://my-url.com/wp-json/wp-v2',
https: true,
},
}
plugins/axios.js
export default ({ $axios, env }) => {
$axios.onRequest(config => {
$axios.setToken(env.WP_API_KEY, 'Bearer');
});
}
And in my page, I'm trying to use the asyncData function to pull data from my WordPress API, as such:
export default {
async asyncData(context) {
const data = await context.$axios.$get('/media');
console.log(data);
return { data };
}
}
I keep receiving a 401 Not Authorized error however, essentially stating that my Authorization: Bearer <token> isn't being passed through. Using Postman however, I can verify that this endpoint does indeed work and returns all of the JSON I need, so the problem must lie in the way I have the axios global header set up.
It's been tough finding any real example on how to set a global header using the Nuxt/Axios module. I see in the docs how to use setToken, however it doesn't exactly show where to place that.
What do I have set up wrong, and how do I fix it?
Pretty typical that I get it working 15 minutes after I post a question.
Setting the header like this instead seems to work. I'm not sure why the setToken method didn't want to work.
export default ({ $axios, env }) => {
$axios.onRequest(config => {
config.headers.common['Authorization'] = `Bearer ${env.WP_API_KEY}`;
});
}
If you are using Nuxt auth module, Here is how I have achived.
// nuxt.config.js
modules: [
'#nuxtjs/auth',
'#nuxtjs/axios',
],
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/auth/login', method: 'post', propertyName: 'accessToken' },
logout: false,
user: { url: '/auth/me', method: 'get', propertyName: false }
},
}
},
redirect: {
login: '/auth/signin',
logout: '/auth/signin',
callback: false,
home: false,
},
cookie: false,
token: {
prefix: 'token',
},
plugins: ['~/plugins/auth.js'],
},
// plugins/axios.js
export default function ({ $axios, $auth, redirect, store }) {
$axios.onRequest((config) => {
config.headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': store.state.auth.tokenlocal, // refers to nuxt.config.js->auth.token
}
})
$axios.onError((error) => {
if (error.response.status === 500) {
redirect('/error')
}
})
}
// store/index.js
export const getters = {
authenticated(state) {
return state.loggedIn;
},
user(state) {
return state.user;
}
};
export const state = () => ({
busy: false,
loggedIn: false,
strategy: "local",
user: false,
});
If you need to customize axios by registering interceptors and changing global config, you have to create a nuxt plugin.
export default ({ $axios, env }) => {
$axios.onRequest(config => {
config.headers.common['Authorization'] = `Bearer ${env.WP_API_KEY}`;
});
}
Adding axios interceptors
Goal: Initially load posts using the Wordpress Rest API via Axios once in a Vue View, and only once during a session of visiting the Vue website.
Current Result: I currently fetch the results successfully and set them in sessionStorage. They display correctly. I want to know/learn if I am accomplishing this correctly and have the process optimized in the best way possible. I've looked up documentation and I think I have it down.
Current Code:
<script>
import Hero from "#/components/Hero.vue";
import axios from "axios";
export default {
name: "About",
components: {
Hero,
},
data: function() {
return {
eatery: [],
};
},
created() {
axios
.get("//localhost:81/wp-json/wp/v2/posts?_embed&per_page=5&categories=2")
.then((response) => {
sessionStorage.setItem("eatery", JSON.stringify(response.data));
})
.catch((error) => {
window.alert(error);
});
},
mounted() {
if (sessionStorage.getItem("eatery")) {
this.eatery = JSON.parse(sessionStorage.getItem("eatery"));
}
},
};
</script>
I would check whether it's in the storage before trying to load it. In your case, it would look like this:
export default {
name: "About",
components: {
Hero,
},
data: function() {
return {
eatery: [],
};
},
loadEatery() {
axios
.get("//localhost:81/wp-json/wp/v2/posts?_embed&per_page=5&categories=2")
.then((response) => {
sessionStorage.setItem("eatery", JSON.stringify(response.data));
return response.data;
})
.catch((error) => {
console.error(error); // for debugging maybe
});
},
mounted() {
if (sessionStorage.getItem("eatery")) {
this.eatery = JSON.parse(sessionStorage.getItem("eatery"));
} else {
loadEatery().then(data => this.eatery = data);
}
},
};
guys, I m new to Vue so don't know how to solve this let me first show code then the problem, I m using Vue-Good-table here is link https://xaksis.github.io/vue-good-demos/#/simple-table
<vue-good-table
title="Product List"
:columns="columns"
:rows="rows"
:paginate="true"
:lineNumbers="true" />
export default {
data(){
return {
columns: [
{
label: 'productname',
field: 'product_name',
filterable: true,
},
{
label: 'productdesc',
field: 'product_desc',
// type: 'number',
html: false,
filterable: true,
},
],
rows:[],//get axios return value
};
},
methods:{
next() {
var _this=this
this.$http.get('http://localhost:3000/api/companyproducts')
.then(function (response) {
_this.rows=response.data
})
.catch(function (error) {
});
}
}
}
now my problem is that how i can append this axios responded value with rows of good table
To "append axios data" you have to install axios first in your project.
So first install axios to your project:
npm install --save axios
Then transform your next method into the follow:
next() {
axios.get('http://localhost:3000/api/companyproducts')
.then(response => {
this.rows = response.data
})
.catch(error => console.log(error))
}
Note that you have also to import axios.So when the script tag starts use:
import axios from 'axios'
Axios is a great package you can learn more here
As i can see in your code you are not using axios but vue-resource.Vue-resource is also good package so you can learn more here
I'm guessing with the code you have, the view does not respond after the http.get completes.
You may be able to do it by configuring rows as a computed property, since this watches it's dependents (i.e row_data) for changes
computed: {
rows: function () {
return this.row_data;
}
}
...
data(){
return {
columns: [
...
],
row_data:[]
};
}
...
methods: {
next() {
var _this=this
this.$http.get('http://localhost:3000/api/companyproducts')
.then(function (response) {
_this.row_data = response.data
})
}
}
...
created: function() {
this.next()
}