@nuxtjs/apollo
Version:
* Nuxt.js module to use [vue-apollo](https://github.com/Akryum/vue-apollo) * uses internally same approach as [vue-cli-plugin-apollo](https://github.com/Akryum/vue-cli-plugin-apollo)
345 lines (285 loc) • 11.5 kB
Markdown
# Apollo inside of NuxtJS
* Nuxt.js module to use [vue-apollo](https://github.com/Akryum/vue-apollo)
* uses internally same approach as [vue-cli-plugin-apollo](https://github.com/Akryum/vue-cli-plugin-apollo)
[](https://www.npmjs.com/package/@nuxtjs/apollo)
[](https://github.com/nuxt-community/apollo-module/blob/master/LICENSE)
## Warning
This version requires Vue 2.6+ with serverPrefetch support. For example:
```bash
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
Install apollo module:
```bash
npm install --save /apollo
# if you are using *.gql or *.graphql files add graphql-tag to your dependencies
npm install --save graphql-tag
```
Add `/apollo` to `modules` section of `nuxt.config.js`
```bash
- clientConfigs: `Object` Config passed to ApolloClient
- default: `Object` // keep in mind that the object will be stringified!
# alternative
- default: `Path` // use this to have more control over the options
- otherClient: `Object` (Optional)
```
```js
{
// Add apollo module
modules: ['/apollo'],
// Give apollo module options
apollo: {
tokenName: 'yourApolloTokenName', // optional, default: apollo-token
tokenExpires: 10, // optional, default: 7 (days)
includeNodeModules: true, // optional, default: false (this includes graphql-tag for node_modules folder)
authenticationType: 'Basic', // optional, default: 'Bearer'
// (Optional) Default 'apollo' definition
defaultOptions: {
// See 'apollo' definition
// For example: default query options
$query: {
loadingKey: 'loading',
fetchPolicy: 'cache-and-network',
},
},
// optional
errorHandler (error) {
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
},
// required
clientConfigs: {
default: {
// required
httpEndpoint: 'http://localhost:4000',
// optional
// See https://www.apollographql.com/docs/link/links/http.html#options
httpLinkOptions: {
credentials: 'same-origin'
},
// You can use `wss` for secure connection (recommended in production)
// Use `null` to disable subscriptions
wsEndpoint: 'ws://localhost:4000', // optional
// LocalStorage token
tokenName: 'apollo-token', // optional
// Enable Automatic Query persisting with Apollo Engine
persisting: false, // Optional
// Use websockets for everything (no HTTP)
// You need to pass a `wsEndpoint` for this to work
websocketsOnly: false // Optional
},
test: {
httpEndpoint: 'http://localhost:5000',
wsEndpoint: 'ws://localhost:5000',
tokenName: 'apollo-token'
},
// alternative: user path to config which returns exact same config options
test2: '~/plugins/my-alternative-apollo-config.js'
}
}
}
```
```js
// plugins/my-alternative-apollo-config.js
export default function(context){
return {
httpEndpoint: 'http://localhost:4000/graphql-alt',
getAuth:() => 'Bearer my-static-token' // use this method to overwrite functions
}
}
```
## 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](https://github.com/Akryum/vue-cli-plugin-apollo/blob/master/graphql-client/src/index.js#L15)
Check out [official vue-apollo-cli](https://github.com/Akryum/vue-cli-plugin-apollo) where possible usecases are presented.
#### clientConfigs.default `Object`: required
#### clientConfigs.<your-additional-client-key> `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: <authenticationType> <your token taken from user cookies>" (Eg. `Authorization: Bearer abc123`).
If your backend requires an Authorization header in the format "Authorization: <your token>", 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.
## Usage
Once the setup is completed you have a successfully enabled `vue-apollo` in your project. Checkout [Official example](https://github.com/nuxt/nuxt.js/tree/dev/examples/vue-apollo) and [vue-apollo](https://github.com/Akryum/vue-apollo) how to use `vue-apollo` inside your application code
## Authentication
You have following methods for authentication available:
```js
// set your graphql-token
this.$apolloHelpers.onLogin(token /* if not default you can pass in client as second argument, and you can set custom token expiration on third argument */)
// unset your graphql-token
this.$apolloHelpers.onLogout(/* if not default you can pass in client as second argument */)
// get your current token (we persist token in a cookie)
this.$apolloHelpers.getToken(/* you can provide named tokenName if not 'apollo-token' */)
```
Check out the [full example](https://github.com/nuxt-community/apollo-module/tree/master/test/fixture)
For permanent authorization tokens the setup just provide `getAuth` function for each of your endpoint configurations:
```js
apollo: {
clientConfigs: {
default: {
httpEndpoint: 'https://graphql.datocms.com',
getAuth: () => 'Bearer your_token_string'
},
}
},
```
#### User login
```js
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
```js
methods:{
async onLogout () {
await this.$apolloHelpers.onLogout()
},
}
```
#### getToken
```js
// middleware/isAuth.js
export default function ({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
```js
export default {
actions: {
foo (store, payload) {
let client = this.app.apolloProvider.defaultClient
}
}
}
```
##### asyncData/fetch method of page component
```js
export default {
asyncData (context) {
let client = context.app.apolloProvider.defaultClient
}
}
```
##### nuxtServerInit
```js
export default {
nuxtServerInit (store, context) {
let client = context.app.apolloProvider.defaultClient
}
}
```
##### access client or call mutations and queries of any method inside of component
```js
export default {
methods:{
foo(){
// receive the associated Apollo client
const client = this.$apollo.getClient()
// most likely you would call mutations like following:
this.$apollo.mutate({mutation, variables})
// but you could also call queries like this:
this.$apollo.query({query, variables})
.then(({ data }) => {
// do what you want with data
})
}
}
}
```
Once you get the client, you can access its methods and properties. See [API Reference](https://akryum.github.io/vue-apollo/api/dollar-apollo.html)
#### Smart queries on any component
```js
export default {
apollo: {
foo: {
query: fooGql,
variables () {
return {
myVar: this.myVar
}
}
}
}
}
```
See [vue-apollo documentation](https://akryum.github.io/vue-apollo/guide/apollo/queries.html) for more information on smart queries
#### Add GQL file recognition on node_modules
```js
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:
```js
// nuxt.config.js
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://github.com/apollographql/apollo-client/blob/master/Upgrade.md
## Troubleshooting
### Use of *.gql files
To use *gql|graphql files you need to add following dependency to your project:
```
yarn add graphql-tag
# alternative
npm install graphql-tag
```
### 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
```
// .env
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:
```gql
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
```