Nuxt and state management with apollo-link-state (how to ditch Vuex)

20 January, 2019

I got nothing against Vuex, but using it with Apollo doesn't feel quite right. Apollo already comes with a cache so why not utilize that and have single source of truth for all your data?

I've been looking for a guide on how to setup apollo-link-state (local state management) with Nuxt, but there seems to be very little information out there. I did some research and wrote down what I did to make it work.

The Setup

nuxt.config.js

module.exports = {
  ...
  /*
  ** Apollo configuration
  */
  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
    errorHandler (error) {
      console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
    },
    // required
    clientConfigs: {
      default: '@/plugins/apollo-config.js'
    }
  }
}

plugins/apollo-config.js

const resolvers = {
  Mutation: {
    updateHello: (root, { value }, { cache }) => {
      const data = {
        hello: value
      }
      cache.writeData({ data })
      return null
    }
  }
}

const clientState = {
  // Set initial local state.
  defaults: {
    hello: 'Hello World!'
  },
  resolvers,
}

export default function(context) {
  return {
    httpEndpoint: 'http://localhost:4000',
    httpLinkOptions: {
      credentials: 'same-origin'
    },
    wsEndpoint: null,
    tokenName: 'apollo-token',
    persisting: false,
    websocketsOnly: false,
    // return the client state
    clientState
  }
}

Fetch and update the data

ViewHelloComponent.vue

<template>
  <div>
    <p>{{ hello }}</p>
    <button @click="updateHello">
      Update Hello
    </button>
  </div>
</template>
 <script>
  import gql from 'graphql-tag'

  export default {
    apollo: {
      hello: gql`
        query hello {
          hello @client
        }
      `
    },
    methods: {
      updateHello () {
        this.$apollo.mutate({
          mutation: gql`
            mutation updateHello ($value: String!) {
              updateHello (value: $value) @client
            }
          `,
          variables: {
            value: 'Hello from apollo-link-state!'
          }
        })
      }
    }
  }
  </script>

Just using Vue?

clientState documentation from vue-plugin-apollo

Example repo

https://github.com/ameistad/nuxt-apollo-link-state.