Apollo inside of NuxtJS
Warning
This version requires Vue 2.6+ with serverPrefetch support. For example:
npm install --save vue@2.6.6 vue-template-compiler@2.6.6 vue-server-renderer@2.6.6
Sometime you may need to remove/rebuild package-lock.json/yarn.lock to make it work.
Setup
1- Install apollo module
npm install --save @nuxtjs/apollo
or
yarn add @nuxtjs/apollo
2- Load @nuxtjs/apollo
module
export default {
modules: [
'@nuxtjs/apollo',
],
apollo: {
clientConfigs: {
default: {
httpEndpoint: 'http://localhost:4000',
}
}
}
}
3- Loading *.gql
or *.graphql
files (optional)
Install graphql-tag
npm install --save graphql-tag
or
yarn add graphql-tag
:warning: Typescript users
Add a gql.d.ts
file in your sources folder with the following content:
declare module '*.gql' {
import { DocumentNode } from 'graphql'
const content: DocumentNode
export default content
}
declare module '*.graphql' {
import { DocumentNode } from 'graphql'
const content: DocumentNode
export default content
}
Usage
You have a successfully enabled vue-apollo
in your project.
Checkout Official example and vue-apollo official documentation for how to use vue-apollo
inside your application
Advanced configuration
{
modules: ['@nuxtjs/apollo'],
apollo: {
clientConfigs: {
default: '~/plugins/my-alternative-apollo-config.js',
alternativeClient: {
httpEndpoint: 'http://localhost:4000',
browserHttpEndpoint: '/graphql',
httpLinkOptions: {
credentials: 'same-origin'
},
wsEndpoint: 'ws://localhost:4000',
tokenName: 'apollo-token',
persisting: false,
websocketsOnly: false
},
},
defaultOptions: {
$query: {
loadingKey: 'loading',
fetchPolicy: 'cache-and-network',
},
},
watchLoading: '~/plugins/apollo-watch-loading-handler.js',
errorHandler: '~/plugins/apollo-error-handler.js',
authenticationType: 'Bearer',
tokenName: 'apollo-token',
includeNodeModules: true,
cookieAttributes: {
expires: 7,
path: '/',
domain: 'example.com',
secure: false,
},
}
}
Apollo clientOptions
using file configuration
:warning: In case you need to declare functions (like getAuth
or inMemoryCacheOptions.fragmentMatcher
) inside apollo configuration, you MUST define your clientOptions
using an external file
export default (context) => {
return {
httpEndpoint: 'http://localhost:4000/graphql-alt',
getAuth: () => 'Bearer my-static-token',
}
}
watchLoading
example
export default (isLoading, countModifier, nuxtContext) => {
loading += countModifier
console.log('Global loading', loading, countModifier)
}
errorHandler
example
export default ({ graphQLErrors, networkError, operation, forward }, nuxtContext) => {
console.log('Global error handler')
console.log(graphQLErrors, networkError, operation, forward)
}
Options
You can either (in a simple setup) just add an object as described above. If you need to overwrite cache or the default getAuth()
function then use a path to your config file which returns the client config options.
clientConfigs Option
: required
Sets up the apollo client endpoints. All available options for each endpoint you find here
Check out official vue-apollo-cli where possible usecases are presented.
clientConfigs.default Object
: required
clientConfigs. Object|Path
: optional
tokenName String
: optional, default: 'apollo-token'
Token name for the cookie which will be set in case of authentication. You can also provide an option tokenName
in each of your clientConfigs
to overwrite the default. When each request is made, the value of whatever is in this cooke will be sent in an "Authorization" HTTP header as specified by authenticationType
below.
authenticationType String
: optional, default: 'Bearer'
Sets the authentication type for any authorized request. Modify this if the authentication type your GraphQL API requires is not the default Bearer
. All requests will then be sent with the appropriate HTTP header in the format: "Authorization: " (Eg. Authorization: Bearer abc123
).
If your backend requires an Authorization header in the format "Authorization: ", without any prefix, then you should set this value to an empty string.
includeNodeModules Boolean
: optional, default: false
In case you use *.gql
files inside of node_module
folder you can enable the graphql-tag/loader
to parse the files for you.
Authentication
You have following methods for authentication available:
this.$apolloHelpers.onLogin(token )
this.$apolloHelpers.onLogout()
this.$apolloHelpers.getToken()
Check out the full example
User login
export default {
methods: {
async onSubmit () {
const credentials = this.credentials
try {
const res = await this.$apollo.mutate({
mutation: authenticateUserGql,
variables: credentials
}).then(({data}) => data && data.authenticateUser)
await this.$apolloHelpers.onLogin(res.token)
} catch (e) {
console.error(e)
}
},
}
}
User logout
export default {
methods: {
async onLogout () {
await this.$apolloHelpers.onLogout()
},
}
}
getToken
export default ({app, error}) => {
const hasToken = !!app.$apolloHelpers.getToken()
if (!hasToken) {
error({
errorCode:503,
message:'You are not allowed to see this'
})
}
}
Examples to access the defaultClient of your apolloProvider
Vuex actions
export default {
actions: {
foo (store, payload) {
let client = this.app.apolloProvider.defaultClient
}
}
}
asyncData/fetch method of page component
export default {
asyncData (context) {
let client = context.app.apolloProvider.defaultClient
}
}
nuxtServerInit
export default {
nuxtServerInit (store, context) {
let client = context.app.apolloProvider.defaultClient
}
}
access client or call mutations and queries of any method inside of component
export default {
methods: {
foo () {
const client = this.$apollo.getClient()
this.$apollo.mutate({mutation, variables})
this.$apollo.query({query, variables})
.then(({ data }) => {
})
}
}
}
Once you get the client, you can access its methods and properties. See API Reference
Smart queries on any component
export default {
apollo: {
foo: {
query: fooGql,
variables () {
return {
myVar: this.myVar
}
}
}
}
}
See vue-apollo documentation for more information on smart queries
Add GQL file recognition on node_modules
export default {
apollo: {
clientConfigs: {
default: '~/apollo/client-configs/default.js'
},
includeNodeModules: true
}
}
Upgrade
Upgrade Guide apollo-module v3 => v4
Version 4 of this module leaves you with zero configuration. This means we use the best possible approach available from vue-cli-plugin-apollo
and the same configuration behaviour. This means you don't need to wire up your own configuration, simply pass
Edit your configuration as following:
export default {
apollo: {
clientConfigs: {
default:{
httpEndpoint: YOUR_ENDPOINT,
wsEndpoint: YOUR_WS_ENDPOINT
}
}
}
}
Upgrade Guide apollo-client v1 => v2
Version 3 of this module is using apollo-client 2.x. You need to make sure to update all your middle/afterware according to the upgrade guide of apollo-client. Check this source for a reference: https://www.apollographql.com/docs/apollo-server/migration-two-dot/
Troubleshooting
Proxies
CORS errors are most often resolved with proxies. If you see a Cross-Origin-Request error in your client side console look into setting up a proxy. Check out https://github.com/nuxt-community/proxy-module for quick and straight forward setup.
ctx.req.session - req is undefined
This is just a placeholder. You'll want to replace it with whatever storage mechanism you choose to store your token.
Here is an example using local storage : https://github.com/Akryum/vue-apollo/issues/144
Contribute and wire up setup
Setup the required fields in .env
file in root folder
HTTP_ENDPOINT=https://your-endpoint
WS_ENDPOINT=wss://your-endpoint
In index.vue
the login process requires that the gql endpoint enables a mutation which returns a valid token:
mutation authenticateUser($email:String!,$password:String!){
authenticateUser(email: $email, password: $password) {
token
id
}
}
If your gql backend is prepared start running nuxt as follow
npm install
npm run dev